diff --git a/accessible/xpcom/AccEventGen.py b/accessible/xpcom/AccEventGen.py index 6af54c34db..8b2a46f75b 100755 --- a/accessible/xpcom/AccEventGen.py +++ b/accessible/xpcom/AccEventGen.py @@ -40,14 +40,14 @@ def loadEventIDL(parser, includePath, eventname): class Configuration: def __init__(self, filename): config = {} - execfile(filename, config) + exec(compile(open(filename, "rb").read(), filename, 'exec'), config) self.simple_events = config.get('simple_events', []) def firstCap(str): return str[0].upper() + str[1:] def writeAttributeParams(a): - return ("%s a%s" % (a.realtype.nativeType('in'), firstCap(a.name))) + return ("{} a{}".format(a.realtype.nativeType('in'), firstCap(a.name))) def print_header_file(fd, conf, incdirs): idl_paths = set() @@ -64,26 +64,26 @@ def print_header_file(fd, conf, incdirs): for e in conf.simple_events: idl, idl_path = loadEventIDL(p, incdirs, e) idl_paths.add(idl_path) - for iface in filter(lambda p: p.kind == "interface", idl.productions): + for iface in [p for p in idl.productions if p.kind == "interface"]: classname = ("xpcAcc%s" % e) baseinterfaces = interfaces(iface) - fd.write("\nclass %s final : public %s\n" % (classname, iface.name)) + fd.write("\nclass {} final : public {}\n".format(classname, iface.name)) fd.write("{\n") fd.write("public:\n") attributes = allAttributes(iface) - args = map(writeAttributeParams, attributes) - fd.write(" %s(%s) :\n" % (classname, ", ".join(args))) + args = list(map(writeAttributeParams, attributes)) + fd.write(" {}({}) :\n".format(classname, ", ".join(args))) initializers = [] for a in attributes: - initializers.append("m%s(a%s)" % (firstCap(a.name), firstCap(a.name))) + initializers.append("m{}(a{})".format(firstCap(a.name), firstCap(a.name))) fd.write(" %s\n {}\n\n" % ", ".join(initializers)) fd.write(" NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n") fd.write(" NS_DECL_CYCLE_COLLECTION_CLASS(%s)\n" % (classname)) - for iface in filter(lambda i: i.name != "nsISupports", baseinterfaces): + for iface in [i for i in baseinterfaces if i.name != "nsISupports"]: fd.write(" NS_DECL_%s\n" % iface.name.upper()) fd.write("\nprivate:\n") @@ -97,13 +97,13 @@ def print_header_file(fd, conf, incdirs): return idl_paths def interfaceAttributeTypes(idl): - ifaces = filter(lambda p: p.kind == "interface", idl.productions) + ifaces = [p for p in idl.productions if p.kind == "interface"] attributes = [] for i in ifaces: ifaceAttributes = allAttributes(i) attributes.extend(ifaceAttributes) - ifaceAttrs = filter(lambda a: a.realtype.nativeType("in").endswith("*"), attributes) - return map(lambda a: a.realtype.nativeType("in").strip(" *"), ifaceAttrs) + ifaceAttrs = [a for a in attributes if a.realtype.nativeType("in").endswith("*")] + return [a.realtype.nativeType("in").strip(" *") for a in ifaceAttrs] def print_cpp(idl, fd, conf, eventname): for p in idl.productions: @@ -118,7 +118,7 @@ def print_cpp_file(fd, conf, incdirs): includes = [] for e in conf.simple_events: if not e in includes: - includes.append(("nsIAccessible%s" % e)) + includes.append("nsIAccessible%s" % e) types = [] for e in conf.simple_events: @@ -139,38 +139,38 @@ def print_cpp_file(fd, conf, incdirs): def attributeVariableTypeAndName(a): if a.realtype.nativeType('in').endswith('*'): - l = ["nsCOMPtr<%s> m%s;" % (a.realtype.nativeType('in').strip('* '), + l = ["nsCOMPtr<{}> m{};".format(a.realtype.nativeType('in').strip('* '), firstCap(a.name))] elif a.realtype.nativeType('in').count("nsAString"): l = ["nsString m%s;" % firstCap(a.name)] elif a.realtype.nativeType('in').count("nsACString"): l = ["nsCString m%s;" % firstCap(a.name)] else: - l = ["%sm%s;" % (a.realtype.nativeType('in'), + l = ["{}m{};".format(a.realtype.nativeType('in'), firstCap(a.name))] return ", ".join(l) def writeAttributeGetter(fd, classname, a): fd.write("NS_IMETHODIMP\n") - fd.write("%s::Get%s(" % (classname, firstCap(a.name))) + fd.write("{}::Get{}(".format(classname, firstCap(a.name))) if a.realtype.nativeType('in').endswith('*'): - fd.write("%s** a%s" % (a.realtype.nativeType('in').strip('* '), firstCap(a.name))) + fd.write("{}** a{}".format(a.realtype.nativeType('in').strip('* '), firstCap(a.name))) elif a.realtype.nativeType('in').count("nsAString"): fd.write("nsAString& a%s" % firstCap(a.name)) elif a.realtype.nativeType('in').count("nsACString"): fd.write("nsACString& a%s" % firstCap(a.name)) else: - fd.write("%s*a%s" % (a.realtype.nativeType('in'), firstCap(a.name))) + fd.write("{}*a{}".format(a.realtype.nativeType('in'), firstCap(a.name))) fd.write(")\n"); fd.write("{\n"); if a.realtype.nativeType('in').endswith('*'): - fd.write(" NS_IF_ADDREF(*a%s = m%s);\n" % (firstCap(a.name), firstCap(a.name))) + fd.write(" NS_IF_ADDREF(*a{} = m{});\n".format(firstCap(a.name), firstCap(a.name))) elif a.realtype.nativeType('in').count("nsAString"): - fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name))) + fd.write(" a{} = m{};\n".format(firstCap(a.name), firstCap(a.name))) elif a.realtype.nativeType('in').count("nsACString"): - fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name))) + fd.write(" a{} = m{};\n".format(firstCap(a.name), firstCap(a.name))) else: - fd.write(" *a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name))) + fd.write(" *a{} = m{};\n".format(firstCap(a.name), firstCap(a.name))) fd.write(" return NS_OK;\n"); fd.write("}\n\n"); @@ -186,7 +186,7 @@ def interfaces(iface): def allAttributes(iface): attributes = [] for i in interfaces(iface): - attrs = filter(lambda m: isinstance(m, xpidl.Attribute), i.members) + attrs = [m for m in i.members if isinstance(m, xpidl.Attribute)] attributes.extend(attrs) return attributes @@ -194,7 +194,7 @@ def allAttributes(iface): def write_cpp(eventname, iface, fd): classname = "xpcAcc%s" % eventname attributes = allAttributes(iface) - ccattributes = filter(lambda m: m.realtype.nativeType('in').endswith('*'), attributes) + ccattributes = [m for m in attributes if m.realtype.nativeType('in').endswith('*')] fd.write("NS_IMPL_CYCLE_COLLECTION(%s" % classname) for c in ccattributes: fd.write(", m%s" % firstCap(c.name)) diff --git a/build/appini_header.py b/build/appini_header.py index 356a0692e7..f87adf30d4 100644 --- a/build/appini_header.py +++ b/build/appini_header.py @@ -5,11 +5,11 @@ '''Parses a given application.ini file and outputs the corresponding XULAppData structure as a C++ header file''' -import ConfigParser +import configparser import sys def main(output, file): - config = ConfigParser.RawConfigParser() + config = configparser.RawConfigParser() config.read(file) flags = set() try: @@ -20,15 +20,14 @@ def main(output, file): if config.getint('Crash Reporter', 'Enabled') == 1: flags.add('NS_XRE_ENABLE_CRASH_REPORTER') except: pass - appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s)) + appdata = {"{}:{}".format(s, o): config.get(s, o) for s in config.sections() for o in config.options(s)} appdata['flags'] = ' | '.join(flags) if flags else '0' appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL' expected = ('App:vendor', 'App:name', 'App:remotingname', 'App:version', 'App:buildid', 'App:id', 'Gecko:minversion', 'Gecko:maxversion') missing = [var for var in expected if var not in appdata] if missing: - print >>sys.stderr, \ - "Missing values in %s: %s" % (file, ', '.join(missing)) + print("Missing values in {}: {}".format(file, ', '.join(missing)), file=sys.stderr) sys.exit(1) if not 'Crash Reporter:serverurl' in appdata: @@ -57,4 +56,4 @@ if __name__ == '__main__': if len(sys.argv) != 1: main(sys.stdout, sys.argv[1]) else: - print >>sys.stderr, "Usage: %s /path/to/application.ini" % sys.argv[0] + print("Usage: %s /path/to/application.ini" % sys.argv[0], file=sys.stderr) diff --git a/build/build-clang/build-clang.py b/build/build-clang/build-clang.py index 697bbb9b8b..30ac7f5ec7 100755 --- a/build/build-clang/build-clang.py +++ b/build/build-clang/build-clang.py @@ -34,7 +34,7 @@ def symlink(source, link_name): def check_run(args): global DEBUG if DEBUG: - print >> sys.stderr, ' '.join(args) + print(' '.join(args), file=sys.stderr) r = subprocess.call(args) assert r == 0 @@ -43,11 +43,11 @@ def run_in(path, args): d = os.getcwd() global DEBUG if DEBUG: - print >> sys.stderr, 'cd "%s"' % path + print('cd "%s"' % path, file=sys.stderr) os.chdir(path) check_run(args) if DEBUG: - print >> sys.stderr, 'cd "%s"' % d + print('cd "%s"' % d, file=sys.stderr) os.chdir(d) @@ -93,7 +93,7 @@ def build_tar_package(tar, name, base, directory): def copy_dir_contents(src, dest): for f in glob.glob("%s/*" % src): try: - destname = "%s/%s" % (dest, os.path.basename(f)) + destname = "{}/{}".format(dest, os.path.basename(f)) if os.path.isdir(f): shutil.copytree(f, destname) else: @@ -378,7 +378,7 @@ if __name__ == "__main__": extra_cxxflags2 = ["-fPIC", "-static-libstdc++"] if os.environ.has_key('LD_LIBRARY_PATH'): - os.environ['LD_LIBRARY_PATH'] = '%s/lib64/:%s' % (gcc_dir, os.environ['LD_LIBRARY_PATH']); + os.environ['LD_LIBRARY_PATH'] = '{}/lib64/:{}'.format(gcc_dir, os.environ['LD_LIBRARY_PATH']); else: os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir elif is_windows(): diff --git a/build/checksums.py b/build/checksums.py index 9b13b50cb4..abecbe5b6a 100755 --- a/build/checksums.py +++ b/build/checksums.py @@ -81,9 +81,9 @@ def process_files(files, output_filename, digests, strip): short_file = short_file.lstrip('/') else: short_file = file - print >>output, '%s %s %s %s' % (hash, digest, + print('%s %s %s %s' % (hash, digest, os.path.getsize(file), - short_file) + short_file), file=output) def setup_logging(level=logging.DEBUG): '''This function sets up the logging module using a speficiable logging @@ -140,7 +140,7 @@ def main(): try: for digest in options.digests: hashlib.new(digest) - except ValueError, ve: + except ValueError as ve: logger.error('Could not create a "%s" hash object (%s)' % (digest, ve.args[0])) exit(1) diff --git a/build/compare-mozconfig/compare-mozconfigs-wrapper.py b/build/compare-mozconfig/compare-mozconfigs-wrapper.py index e1888eed7e..0950b0231d 100644 --- a/build/compare-mozconfig/compare-mozconfigs-wrapper.py +++ b/build/compare-mozconfig/compare-mozconfigs-wrapper.py @@ -3,7 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from __future__ import unicode_literals import logging import mozunit diff --git a/build/compare-mozconfig/compare-mozconfigs.py b/build/compare-mozconfig/compare-mozconfigs.py index 876e336fe5..d5422f3c50 100644 --- a/build/compare-mozconfig/compare-mozconfigs.py +++ b/build/compare-mozconfig/compare-mozconfigs.py @@ -5,13 +5,12 @@ # originally from http://hg.mozilla.org/build/tools/file/4ab9c1a4e05b/scripts/release/compare-mozconfigs.py -from __future__ import unicode_literals import logging import os import site import sys -import urllib2 +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import difflib FAILURE_CODE = 1 @@ -26,7 +25,7 @@ def make_hg_url(hgHost, repoPath, protocol='https', revision=None, filename=None): """construct a valid hg url from a base hg url (hg.mozilla.org), repoPath, revision and possible filename""" - base = '%s://%s' % (protocol, hgHost) + base = '{}://{}'.format(protocol, hgHost) repo = '/'.join(p.strip('/') for p in [base, repoPath]) if not filename: if not revision: @@ -40,15 +39,15 @@ def make_hg_url(hgHost, repoPath, protocol='https', revision=None, def readConfig(configfile, keys=[], required=[]): c = {} - execfile(configfile, c) + exec(compile(open(configfile, "rb").read(), configfile, 'exec'), c) for k in keys: c = c[k] - items = c.keys() + items = list(c.keys()) err = False for key in required: if key not in items: err = True - log.error("Required item `%s' missing from %s" % (key, c)) + log.error("Required item `{}' missing from {}".format(key, c)) if err: raise ConfigError("Missing at least one item in config, see above") return c @@ -100,7 +99,7 @@ def verify_mozconfigs(mozconfig_pair, nightly_mozconfig_pair, platform, mozconfigWhitelist['nightly'][platform]: continue else: - log.warning("%s not in %s %s!" % ( + log.warning("{} not in {} {}!".format( clean_line, platform, mozconfigWhitelist['nightly'][platform])) else: @@ -122,11 +121,11 @@ def get_mozconfig(path, options): specified should be relative to the root of the hg repository e.g browser/config/mozconfigs/linux32/nightly""" if options.no_download: - return open(path, 'r').readlines() + return open(path).readlines() else: url = make_hg_url(options.hghost, options.branch, 'http', options.revision, path) - return urllib2.urlopen(url).readlines() + return six.moves.urllib.request.urlopen(url).readlines() if __name__ == '__main__': from optparse import OptionParser diff --git a/build/gen_test_packages_manifest.py b/build/gen_test_packages_manifest.py index 1e2a7c3bba..4160774196 100644 --- a/build/gen_test_packages_manifest.py +++ b/build/gen_test_packages_manifest.py @@ -68,7 +68,7 @@ def generate_package_data(args): tests_common = args.tests_common jsshell = args.jsshell - harness_requirements = dict([(k, [tests_common]) for k in ALL_HARNESSES]) + harness_requirements = {k: [tests_common] for k in ALL_HARNESSES} harness_requirements['jittest'].append(jsshell) for harness in PACKAGE_SPECIFIED_HARNESSES + OPTIONAL_PACKAGES: pkg_name = getattr(args, harness, None) diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index 22eaa3425a..f393c8f320 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from __future__ import print_function, unicode_literals import errno import json @@ -12,7 +11,7 @@ import random import subprocess import sys import uuid -import __builtin__ +import builtins from types import ModuleType @@ -41,7 +40,7 @@ SEARCH_PATHS = [ 'python/blessings', 'python/compare-locales', 'python/configobj', - 'python/futures', + # 'python/futures', # Python 3 has concurrent.futures built-in 'python/jsmin', 'python/psutil', 'python/pylru', @@ -173,9 +172,9 @@ def bootstrap(topsrcdir, mozilla_dir=None): # Ensure we are running Python 2.7+. We put this check here so we generate a # user-friendly error message rather than a cryptic stack trace on module # import. - if sys.version_info[0] != 2 or sys.version_info[1] < 7: - print('Python 2.7 or above (but not Python 3) is required to run mach.') - print('You are running Python', platform.python_version()) + if sys.version_info[0] < 3: + print('Python 3 is required to run mach.') + print(('You are running Python', platform.python_version())) sys.exit(1) # Global build system and mach state is stored in a central directory. By @@ -233,10 +232,14 @@ def bootstrap(topsrcdir, mozilla_dir=None): )) if platform.system() == 'Linux': - dist = list(platform.linux_distribution()) + try: + import distro + dist = [distro.name(), distro.version(), distro.codename()] + except ImportError: + dist = ['', '', ''] data['system']['linux_distribution'] = dist elif platform.system() == 'Windows': - win32_ver=list((platform.win32_ver())), + win32_ver=list(platform.win32_ver()), data['system']['win32_ver'] = win32_ver elif platform.system() == 'Darwin': # mac version is a special Cupertino snowflake @@ -350,7 +353,7 @@ def bootstrap(topsrcdir, mozilla_dir=None): # and caveats. # Objdirs outside the source directory are ignored because in most cases, if # a .pyc/.pyo file exists there, a .py file will be next to it anyways. -class ImportHook(object): +class ImportHook: def __init__(self, original_import): self._original_import = original_import # Assume the source directory is the parent directory of the one @@ -360,7 +363,7 @@ class ImportHook(object): self._modules = set() def __call__(self, name, globals=None, locals=None, fromlist=None, - level=-1): + level=0): # name might be a relative import. Instead of figuring out what that # resolves to, which is complex, just rely on the real import. # Since we don't know the full module name, we can't check sys.modules, @@ -409,4 +412,4 @@ class ImportHook(object): # Install our hook -__builtin__.__import__ = ImportHook(__builtin__.__import__) +builtins.__import__ = ImportHook(builtins.__import__) diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure index 7869764870..79ba7a8e68 100644 --- a/build/moz.configure/init.configure +++ b/build/moz.configure/init.configure @@ -133,7 +133,7 @@ option(env='PYTHON', nargs=1, help='Python interpreter') @imports(_from='mozbuild.configure.util', _import='LineIO') @imports(_from='mozbuild.virtualenv', _import='VirtualenvManager') @imports(_from='mozbuild.virtualenv', _import='verify_python_version') -@imports('distutils.sysconfig') +@imports('sysconfig') def virtualenv_python(env_python, build_env, mozconfig, help): if help: return @@ -193,7 +193,7 @@ def virtualenv_python(env_python, build_env, mozconfig, help): sys.exit(subprocess.call([python] + sys.argv)) # We are now in the virtualenv - if not distutils.sysconfig.get_python_lib(): + if not sysconfig.get_path('purelib'): die('Could not determine python site packages directory') return python @@ -212,7 +212,7 @@ def early_options(): def early_options(): return set( option.env - for option in __sandbox__._options.itervalues() + for option in __sandbox__._options.values() if option.env ) return early_options @@ -240,17 +240,17 @@ def mozconfig_options(mozconfig, help): log.info(' %s' % arg) helper.add(arg, origin='mozconfig', args=helper._args) - for key, value in mozconfig['env']['added'].iteritems(): + for key, value in mozconfig['env']['added'].items(): add(key, value) os.environ[key] = value - for key, (_, value) in mozconfig['env']['modified'].iteritems(): + for key, (_, value) in mozconfig['env']['modified'].items(): add(key, value) os.environ[key] = value - for key, value in mozconfig['vars']['added'].iteritems(): + for key, value in mozconfig['vars']['added'].items(): # mozconfig_loader adds _IS_SET variables that are irrelevant if not key.endswith('_IS_SET'): add(key, value) - for key, (_, value) in mozconfig['vars']['modified'].iteritems(): + for key, (_, value) in mozconfig['vars']['modified'].items(): add(key, value) @@ -400,7 +400,12 @@ def split_triplet(triplet): def config_sub(shell, triplet): config_sub = os.path.join(os.path.dirname(__file__), '..', 'autoconf', 'config.sub') - return subprocess.check_output([shell, config_sub, triplet]).strip() + result = subprocess.check_output([shell, config_sub, triplet]).strip() + try: + result = result.decode('utf-8') + except AttributeError: + pass + return result @depends('--host', shell) @@ -411,6 +416,10 @@ def host(value, shell): config_guess = os.path.join(os.path.dirname(__file__), '..', 'autoconf', 'config.guess') host = subprocess.check_output([shell, config_guess]).strip() + try: + host = host.decode('utf-8') + except AttributeError: + pass else: host = value[0] @@ -761,7 +770,7 @@ def enabled_in_nightly(milestone, _): def all_configure_options(_): result = [] previous = None - for option in __sandbox__._options.itervalues(): + for option in __sandbox__._options.values(): # __sandbox__._options contains items for both option.name and # option.env. But it's also an OrderedDict, meaning both are # consecutive. diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure index e08d093080..ba9200172e 100644 --- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -79,7 +79,7 @@ def prepare_configure(old_configure, mozconfig, awk, m4, build_env, shell, # Make old-configure append to config.log, where we put our own log. # This could be done with a m4 macro, but it's way easier this way - script = script.replace('>./config.log', '>>./config.log') + script = script.replace(b'>./config.log', b'>>./config.log') with open(old_configure, 'wb') as fh: fh.write(script) @@ -346,7 +346,7 @@ def old_configure(prepare_configure, extra_old_configure_args, all_options, # Every variation of the exec() function I tried led to: # SyntaxError: unqualified exec is not allowed in function 'main' it # contains a nested function with free variables - exec code in raw_config + exec(code, raw_config) # Ensure all the flags known to old-configure appear in the # @old_configure_options above. @@ -380,9 +380,9 @@ def set_old_configure_define(name, value): def post_old_configure(raw_config): for k, v in raw_config['substs']: set_old_configure_config( - k[1:-1], v[1:-1] if isinstance(v, types.StringTypes) else v) + k[1:-1], v[1:-1] if isinstance(v, str) else v) - for k, v in dict(raw_config['defines']).iteritems(): + for k, v in dict(raw_config['defines']).items(): set_old_configure_define(k[1:-1], v[1:-1]) set_old_configure_config('non_global_defines', diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index de45e74744..04b7bc4ba7 100644 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -236,7 +236,7 @@ def get_compiler_info(compiler, language): ('CPU', CPU_preprocessor_checks), ('KERNEL', kernel_preprocessor_checks), ): - for n, (value, condition) in enumerate(preprocessor_checks.iteritems()): + for n, (value, condition) in enumerate(preprocessor_checks.items()): check += dedent('''\ #%(if)s %(condition)s %%%(name)s "%(value)s" @@ -269,7 +269,7 @@ def get_compiler_info(compiler, language): # have non-ASCII characters. Treat the output as bytearray. data = {} for line in result.splitlines(): - if line.startswith(b'%'): + if line.startswith('%'): k, _, v = line.partition(' ') k = k.lstrip('%') data[k] = v.replace(' ', '').lstrip('"').rstrip('"') @@ -601,7 +601,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None, if cross_compiling and other_compiler.type == 'clang': return namespace(**{ k: [] if k == 'flags' else v - for k, v in other_compiler.__dict__.iteritems() + for k, v in other_compiler.__dict__.items() }) # Normally, we'd use `var` instead of `_var`, but the interaction with diff --git a/build/moz.configure/util.configure b/build/moz.configure/util.configure index 6bb97574c2..4860c339de 100644 --- a/build/moz.configure/util.configure +++ b/build/moz.configure/util.configure @@ -35,6 +35,10 @@ def check_cmd_output(*args, **kwargs): stdout, stderr = proc.communicate() retcode = proc.wait() if retcode == 0: + try: + stdout = stdout.decode('utf-8', errors='replace') + except AttributeError: + pass return stdout log.debug('The command returned non-zero exit status %d.', diff --git a/build/pgo/genpgocert.py b/build/pgo/genpgocert.py index c58bcd40d6..30f4aa2e1a 100644 --- a/build/pgo/genpgocert.py +++ b/build/pgo/genpgocert.py @@ -21,9 +21,9 @@ from mozfile import NamedTemporaryFile from mozprofile.permissions import ServerLocations dbFiles = [ - re.compile("^cert[0-9]+\.db$"), - re.compile("^key[0-9]+\.db$"), - re.compile("^secmod\.db$") + re.compile(r"^cert[0-9]+\.db$"), + re.compile(r"^key[0-9]+\.db$"), + re.compile(r"^secmod\.db$") ] def unlinkDbFiles(path): @@ -48,7 +48,7 @@ def runUtil(util, args, inputdata = None): pathvar = "LD_LIBRARY_PATH" app_path = os.path.dirname(util) if pathvar in env: - env[pathvar] = "%s%s%s" % (app_path, os.pathsep, env[pathvar]) + env[pathvar] = "{}{}{}".format(app_path, os.pathsep, env[pathvar]) else: env[pathvar] = app_path proc = subprocess.Popen([util] + args, env=env, @@ -58,7 +58,7 @@ def runUtil(util, args, inputdata = None): def createRandomFile(randomFile): - for count in xrange(0, 2048): + for count in range(0, 2048): randomFile.write(chr(random.randint(0, 255))) @@ -125,14 +125,14 @@ def createSSLServerCertificate(build, srcDir): iterator = iter(locations) # Skips the first entry, I don't know why: bug 879740 - iterator.next() + next(iterator) locationsParam = "" firstLocation = "" for loc in iterator: if loc.scheme == "https" and "nocert" not in loc.options: customCertOption = False - customCertRE = re.compile("^cert=(?:\w+)") + customCertRE = re.compile(r"^cert=(?:\w+)") for option in loc.options: match = customCertRE.match(option) if match: @@ -148,7 +148,7 @@ def createSSLServerCertificate(build, srcDir): firstLocation = loc.host if not firstLocation: - print "Nothing to generate, no automatic secure hosts specified" + print("Nothing to generate, no automatic secure hosts specified") else: createRandomFile(rndfile) @@ -162,7 +162,7 @@ def createSSLServerCertificate(build, srcDir): return 0 if len(sys.argv) == 1: - print "Specify --gen-server or --gen-ca" + print("Specify --gen-server or --gen-ca") sys.exit(1) build = MozbuildObject.from_environment() @@ -170,23 +170,23 @@ certdir = os.path.join(build.topsrcdir, "build", "pgo", "certs") if sys.argv[1] == "--gen-server": certificateStatus = createSSLServerCertificate(build, certdir) if certificateStatus: - print "TEST-UNEXPECTED-FAIL | SSL Server Certificate generation" + print("TEST-UNEXPECTED-FAIL | SSL Server Certificate generation") sys.exit(certificateStatus) if sys.argv[1] == "--gen-ca": certificateStatus = createCertificateAuthority(build, certdir) if certificateStatus: - print "TEST-UNEXPECTED-FAIL | Certificate Authority generation" + print("TEST-UNEXPECTED-FAIL | Certificate Authority generation") else: - print "\n\n" - print "===================================================" - print " IMPORTANT:" - print " To use this new certificate authority in tests" - print " run 'make' at testing/mochitest" - print "===================================================" + print("\n\n") + print("===================================================") + print(" IMPORTANT:") + print(" To use this new certificate authority in tests") + print(" run 'make' at testing/mochitest") + print("===================================================") sys.exit(certificateStatus) -print "Invalid option specified" +print("Invalid option specified") sys.exit(1) diff --git a/build/pgo/profileserver.py b/build/pgo/profileserver.py index adc93d9b13..34416f72e8 100644 --- a/build/pgo/profileserver.py +++ b/build/pgo/profileserver.py @@ -63,7 +63,7 @@ if __name__ == '__main__': vcdir = os.path.abspath(os.path.join(env[e], '../../VC/bin')) if os.path.exists(vcdir): - env['PATH'] = '%s;%s' % (vcdir, env['PATH']) + env['PATH'] = '{};{}'.format(vcdir, env['PATH']) break # Run Firefox a first time to initialize its profile @@ -77,7 +77,7 @@ if __name__ == '__main__': jarlog = os.getenv("JARLOG_FILE") if jarlog: env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog) - print "jarlog: %s" % env["MOZ_JAR_LOG_FILE"] + print("jarlog: %s" % env["MOZ_JAR_LOG_FILE"]) cmdargs = ["http://localhost:%d/index.html" % PORT] runner = FirefoxRunner(profile=profile, diff --git a/build/ppCheck.py b/build/ppCheck.py index 1e27ca1715..f072720bfa 100644 --- a/build/ppCheck.py +++ b/build/ppCheck.py @@ -1,9 +1,8 @@ #!/usr/bin/env python -from __future__ import print_function import os, sys -if not len(sys.argv) is 2 or not os.path.exists(sys.argv[1]): +if not len(sys.argv) == 2 or not os.path.exists(sys.argv[1]): print("\nYou did not supply a valid path to check.") exit(1) else: @@ -65,7 +64,7 @@ PP_BAD_FILES = list(dict.fromkeys(PP_BAD_FILES)) print('Done!') if len(PP_BAD_FILES) > 0: - print("\nWARNING: The following {0} file(s) in {1} may require preprocessing:\n".format(len(PP_BAD_FILES), DIST_PATH)) + print("\nWARNING: The following {} file(s) in {} may require preprocessing:\n".format(len(PP_BAD_FILES), DIST_PATH)) for file in PP_BAD_FILES: print(file) diff --git a/build/pymake/mkformat.py b/build/pymake/mkformat.py index 41dd761b2f..29e0407e47 100755 --- a/build/pymake/mkformat.py +++ b/build/pymake/mkformat.py @@ -6,8 +6,8 @@ import pymake.parser filename = sys.argv[1] source = None -with open(filename, 'rU') as fh: +with open(filename) as fh: source = fh.read() statements = pymake.parser.parsestring(source, filename) -print statements.to_source() +print(statements.to_source()) diff --git a/build/pymake/mkparse.py b/build/pymake/mkparse.py index 253683948a..aa94b81bab 100755 --- a/build/pymake/mkparse.py +++ b/build/pymake/mkparse.py @@ -4,9 +4,9 @@ import sys import pymake.parser for f in sys.argv[1:]: - print "Parsing %s" % f - fd = open(f, 'rU') + print("Parsing %s" % f) + fd = open(f) s = fd.read() fd.close() stmts = pymake.parser.parsestring(s, f) - print stmts + print(stmts) diff --git a/build/pymake/pymake/builtins.py b/build/pymake/pymake/builtins.py index eb6f2e11bd..1ab3328195 100644 --- a/build/pymake/pymake/builtins.py +++ b/build/pymake/pymake/builtins.py @@ -2,7 +2,7 @@ import errno, sys, os, shutil, time from getopt import getopt, GetoptError -from process import PythonException +from .process import PythonException __all__ = ["mkdir", "rm", "sleep", "touch"] @@ -13,8 +13,8 @@ def mkdir(args): """ try: opts, args = getopt(args, "p", ["parents"]) - except GetoptError, e: - raise PythonException, ("mkdir: %s" % e, 1) + except GetoptError as e: + raise PythonException("mkdir: %s" % e, 1) parents = False for o, a in opts: if o in ('-p', '--parents'): @@ -25,11 +25,11 @@ def mkdir(args): os.makedirs(f) else: os.mkdir(f) - except OSError, e: + except OSError as e: if e.errno == errno.EEXIST and parents: pass else: - raise PythonException, ("mkdir: %s" % e, 1) + raise PythonException("mkdir: %s" % e, 1) def rm(args): """ @@ -38,8 +38,8 @@ def rm(args): """ try: opts, args = getopt(args, "rRf", ["force", "recursive"]) - except GetoptError, e: - raise PythonException, ("rm: %s" % e, 1) + except GetoptError as e: + raise PythonException("rm: %s" % e, 1) force = False recursive = False for o, a in opts: @@ -50,7 +50,7 @@ def rm(args): for f in args: if os.path.isdir(f): if not recursive: - raise PythonException, ("rm: cannot remove '%s': Is a directory" % f, 1) + raise PythonException("rm: cannot remove '%s': Is a directory" % f, 1) else: shutil.rmtree(f, force) elif os.path.exists(f): @@ -58,9 +58,9 @@ def rm(args): os.unlink(f) except: if not force: - raise PythonException, ("rm: failed to remove '%s': %s" % (f, sys.exc_info()[0]), 1) + raise PythonException("rm: failed to remove '{}': {}".format(f, sys.exc_info()[0]), 1) elif not force: - raise PythonException, ("rm: cannot remove '%s': No such file or directory" % f, 1) + raise PythonException("rm: cannot remove '%s': No such file or directory" % f, 1) def sleep(args): """ @@ -70,7 +70,7 @@ def sleep(args): values = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400} for a in args: multiplier = 1 - for k, v in values.iteritems(): + for k, v in values.items(): if a.endswith(k): a = a[:-1] multiplier = v @@ -79,7 +79,7 @@ def sleep(args): f = float(a) total += f * multiplier except ValueError: - raise PythonException, ("sleep: invalid time interval '%s'" % a, 1) + raise PythonException("sleep: invalid time interval '%s'" % a, 1) time.sleep(total) def touch(args): @@ -88,16 +88,16 @@ def touch(args): """ try: opts, args = getopt(args, "t:") - except GetoptError, e: - raise PythonException, ("touch: %s" % e, 1) + except GetoptError as e: + raise PythonException("touch: %s" % e, 1) opts = dict(opts) times = None if '-t' in opts: import re from time import mktime, localtime - m = re.match('^(?P(?:\d\d)?\d\d)?(?P\d\d)(?P\d\d)(?P\d\d)(?P\d\d)(?:\.(?P\d\d))?$', opts['-t']) + m = re.match(r'^(?P(?:\d\d)?\d\d)?(?P\d\d)(?P\d\d)(?P\d\d)(?P\d\d)(?:\.(?P\d\d))?$', opts['-t']) if not m: - raise PythonException, ("touch: invalid date format '%s'" % opts['-t'], 1) + raise PythonException("touch: invalid date format '%s'" % opts['-t'], 1) def normalized_field(m, f): if f == 'Y': if m.group(f) is None: diff --git a/build/pymake/pymake/command.py b/build/pymake/pymake/command.py index cd68e4fdb2..3d18a2cc12 100644 --- a/build/pymake/pymake/command.py +++ b/build/pymake/pymake/command.py @@ -62,7 +62,7 @@ def parsemakeflags(env): return opts def _version(*args): - print """pymake: GNU-compatible make program + print("""pymake: GNU-compatible make program Copyright (C) 2009 The Mozilla Foundation This is free software; see the source for copying conditions. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR @@ -71,7 +71,7 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE.""" +DEALINGS IN THE SOFTWARE.""") _log = logging.getLogger('pymake.execution') @@ -95,7 +95,7 @@ class _MakeContext(object): def remakecb(self, remade, error=None): if error is not None: - print error + print(error) self.context.defer(self.cb, 2) return @@ -124,15 +124,15 @@ class _MakeContext(object): self.makefile.include(f) self.makefile.finishparsing() self.makefile.remakemakefiles(self.remakecb) - except util.MakeError, e: - print e + except util.MakeError as e: + print(e) self.context.defer(self.cb, 2) return if len(self.targets) == 0: if self.makefile.defaulttarget is None: - print "No target specified and no default target found." + print("No target specified and no default target found.") self.context.defer(self.cb, 2) return @@ -154,7 +154,7 @@ class _MakeContext(object): if not len(self.realtargets): if self.options.printdir: - print "make.py[%i]: Leaving directory '%s'" % (self.makelevel, self.workdir) + print("make.py[%i]: Leaving directory '%s'" % (self.makelevel, self.workdir)) sys.stdout.flush() self.context.defer(self.cb, 0) @@ -255,24 +255,24 @@ def main(args, env, cwd, cb): context = process.getcontext(options.jobcount) if options.printdir: - print "make.py[%i]: Entering directory '%s'" % (makelevel, workdir) + print("make.py[%i]: Entering directory '%s'" % (makelevel, workdir)) sys.stdout.flush() if len(options.makefiles) == 0: if os.path.exists(util.normaljoin(workdir, 'Makefile')): options.makefiles.append('Makefile') else: - print "No makefile found" + print("No makefile found") cb(2) return ostmts, targets, overrides = parserdata.parsecommandlineargs(arguments) _MakeContext(makeflags, makelevel, workdir, context, env, targets, options, ostmts, overrides, cb) - except (util.MakeError), e: - print e + except (util.MakeError) as e: + print(e) if options.printdir: - print "make.py[%i]: Leaving directory '%s'" % (makelevel, workdir) + print("make.py[%i]: Leaving directory '%s'" % (makelevel, workdir)) sys.stdout.flush() cb(2) return diff --git a/build/pymake/pymake/data.py b/build/pymake/pymake/data.py index dcd7e92258..fc67e91d0f 100644 --- a/build/pymake/pymake/data.py +++ b/build/pymake/pymake/data.py @@ -3,13 +3,11 @@ A representation of makefile data structures. """ import logging, re, os, sys -import parserdata, parser, functions, process, util, implicit +from . import parserdata, parser, functions, process, util, implicit from cStringIO import StringIO +from functools import reduce -if sys.version_info[0] < 3: - str_type = basestring -else: - str_type = str +str_type = str _log = logging.getLogger('pymake.data') @@ -69,7 +67,7 @@ def _if_else(c, t, f): return f() -class BaseExpansion(object): +class BaseExpansion: """Base class for expansions. A make expansion is the parsed representation of a string, which may @@ -95,8 +93,7 @@ class BaseExpansion(object): child expansions and extract all functions in the tree. """ # An empty generator. Yeah, it's weird. - for x in []: - yield x + yield from [] def variable_references(self, descend=False): """Obtain all variable references in this expansion. @@ -186,7 +183,7 @@ class StringExpansion(BaseExpansion): return self.s, False def __repr__(self): - return "Exp<%s>(%r)" % (self.loc, self.s) + return "Exp<{}>({!r})".format(self.loc, self.s) def __eq__(self, other): """We only compare the string contents.""" @@ -355,11 +352,10 @@ class Expansion(BaseExpansion, list): if descend: for exp in e.expansions(descend=True): - for f in exp.functions(descend=True): - yield f + yield from exp.functions(descend=True) def __repr__(self): - return "" % ([e for e, isfunc in self],) + return "".format([e for e, isfunc in self]) def to_source(self, escape_variables=False, escape_comments=False): parts = [] @@ -405,7 +401,7 @@ class Expansion(BaseExpansion, list): if len(a) != len(b): return False - for i in xrange(len(self)): + for i in range(len(self)): e1, is_func1 = a[i] e2, is_func2 = b[i] @@ -423,7 +419,7 @@ class Expansion(BaseExpansion, list): def __ne__(self, other): return not self.__eq__(other) -class Variables(object): +class Variables: """ A mapping from variable names to variables. Variables have flavor, source, and value. The value is an expansion object. @@ -447,7 +443,7 @@ class Variables(object): self.parent = parent def readfromenvironment(self, env): - for k, v in env.iteritems(): + for k, v in env.items(): self.set(k, self.FLAVOR_RECURSIVE, self.SOURCE_ENVIRONMENT, v) def get(self, name, expand=True): @@ -462,7 +458,7 @@ class Variables(object): flavor, source, valuestr, valueexp = self._map.get(name, (None, None, None, None)) if flavor is not None: if expand and flavor != self.FLAVOR_SIMPLE and valueexp is None: - d = parser.Data.fromstring(valuestr, parserdata.Location("Expansion of variables '%s'" % (name,), 1, 0)) + d = parser.Data.fromstring(valuestr, parserdata.Location("Expansion of variables '{}'".format(name), 1, 0)) valueexp, t, o = parser.parsemakesyntax(d, 0, (), parser.iterdata) self._map[name] = flavor, source, valuestr, valueexp @@ -495,7 +491,7 @@ class Variables(object): if flavor == self.FLAVOR_RECURSIVE: val = valueexp else: - val = Expansion.fromstring(valuestr, "Expansion of variable '%s'" % (name,)) + val = Expansion.fromstring(valuestr, "Expansion of variable '{}'".format(name)) return flavor, source, val @@ -512,7 +508,7 @@ class Variables(object): prevflavor, prevsource, prevvalue = self.get(name) if prevsource is not None and source > prevsource and not force: # TODO: give a location for this warning - _log.info("not setting variable '%s', set by higher-priority source to value '%s'" % (name, prevvalue)) + _log.info("not setting variable '{}', set by higher-priority source to value '{}'".format(name, prevvalue)) return self._map[name] = flavor, source, value, None @@ -531,7 +527,7 @@ class Variables(object): return if prevflavor == self.FLAVOR_SIMPLE: - d = parser.Data.fromstring(value, parserdata.Location("Expansion of variables '%s'" % (name,), 1, 0)) + d = parser.Data.fromstring(value, parserdata.Location("Expansion of variables '{}'".format(name), 1, 0)) valueexp, t, o = parser.parsemakesyntax(d, 0, (), parser.iterdata) val = valueexp.resolvestr(makefile, variables, [name]) @@ -547,13 +543,13 @@ class Variables(object): self.set(k, flavor, source, value) def __iter__(self): - for k, (flavor, source, value, valueexp) in self._map.iteritems(): + for k, (flavor, source, value, valueexp) in self._map.items(): yield k, flavor, source, value def __contains__(self, item): return item in self._map -class Pattern(object): +class Pattern: """ A pattern is a string, possibly with a % substitution character. From the GNU make manual: @@ -561,7 +557,7 @@ class Pattern(object): would otherwise quote '%' charcters can be quoted with more backslashes. Backslashes that quote '%' characters or other backslashes are removed from the pattern before it is compared t file names or has a stem substituted into it. Backslashes that are not in danger of quoting '%' - characters go unmolested. For example, the pattern the\%weird\\%pattern\\ has `the%weird\' preceding + characters go unmolested. For example, the pattern the\\%weird\\%pattern\\ has `the%weird\' preceding the operative '%' character, and 'pattern\\' following it. The final two backslashes are left alone because they cannot affect any '%' character. @@ -658,7 +654,7 @@ class Pattern(object): stem = self.match(word) if stem is None: if mustmatch: - raise DataError("target '%s' doesn't match pattern" % (word,)) + raise DataError("target '{}' doesn't match pattern".format(word)) return word if not self.ispattern(): @@ -668,7 +664,7 @@ class Pattern(object): return Pattern(replacement).resolve('', stem) def __repr__(self): - return "" % (self.data,) + return "".format(self.data) _backre = re.compile(r'[%\\]') def __str__(self): @@ -677,7 +673,7 @@ class Pattern(object): return self._backre.sub(r'\\\1', self.data[0]) + '%' + self.data[1] -class RemakeTargetSerially(object): +class RemakeTargetSerially: __slots__ = ('target', 'makefile', 'indent', 'rlist') def __init__(self, target, makefile, indent, rlist): @@ -722,7 +718,7 @@ class RemakeTargetSerially(object): else: self.rlist[0].resolvedeps(True, self.resolvecb) -class RemakeTargetParallel(object): +class RemakeTargetParallel: __slots__ = ('target', 'makefile', 'indent', 'rlist', 'rulesremaining', 'currunning') def __init__(self, target, makefile, indent, rlist): @@ -793,7 +789,7 @@ class RemakeTargetParallel(object): self.currunning = False self.runnext() -class RemakeRuleContext(object): +class RemakeRuleContext: def __init__(self, target, makefile, rule, deps, targetstack, avoidremakeloop): self.target = target @@ -864,7 +860,7 @@ class RemakeRuleContext(object): assert error in (True, False) if error: - print "<%s>: Found error" % self.target.target + print("<%s>: Found error" % self.target.target) self.error = True if didanything: self.didanything = True @@ -949,8 +945,8 @@ class RemakeRuleContext(object): self.target.didanything = True try: self.commands = [c for c in self.rule.getcommands(self.target, self.makefile)] - except util.MakeError, e: - print e + except util.MakeError as e: + print(e) sys.stdout.flush() cb(error=True) return @@ -963,7 +959,7 @@ MAKESTATE_NONE = 0 MAKESTATE_FINISHED = 1 MAKESTATE_WORKING = 2 -class Target(object): +class Target: """ An actual (non-pattern) target. @@ -1027,7 +1023,7 @@ class Target(object): candidates = [] # list of PatternRuleInstance - hasmatch = util.any((r.hasspecificmatch(file) for r in makefile.implicitrules)) + hasmatch = util.any(r.hasspecificmatch(file) for r in makefile.implicitrules) for r in makefile.implicitrules: if r in rulestack: @@ -1109,7 +1105,7 @@ class Target(object): assert makefile.parsingfinished if self.target in targetstack: - raise ResolutionError("Recursive dependency: %s -> %s" % ( + raise ResolutionError("Recursive dependency: {} -> {}".format( " -> ".join(targetstack), self.target)) targetstack = targetstack + [self.target] @@ -1136,9 +1132,9 @@ class Target(object): # depend on it are always out of date. This is like .FORCE but more # compatible with other makes. # Otherwise, we don't know how to make it. - if not len(self.rules) and self.mtime is None and not util.any((len(rule.prerequisites) > 0 - for rule in self.rules)): - raise ResolutionError("No rule to make target '%s' needed by %r" % (self.target, + if not len(self.rules) and self.mtime is None and not util.any(len(rule.prerequisites) > 0 + for rule in self.rules): + raise ResolutionError("No rule to make target '{}' needed by {!r}".format(self.target, targetstack)) if recursive: @@ -1283,9 +1279,9 @@ class Target(object): try: self.resolvedeps(makefile, targetstack, [], False) - except util.MakeError, e: + except util.MakeError as e: if printerror: - print e + print(e) self.error = True self.notifydone(makefile) return @@ -1334,8 +1330,8 @@ def filepart(p): def setautomatic(v, name, plist): v.set(name, Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join(plist)) - v.set(name + 'D', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join((dirpart(p) for p in plist))) - v.set(name + 'F', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join((filepart(p) for p in plist))) + v.set(name + 'D', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join(dirpart(p) for p in plist)) + v.set(name + 'F', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join(filepart(p) for p in plist)) def setautomaticvariables(v, makefile, target, prerequisites): prtargets = [makefile.gettarget(p) for p in prerequisites] @@ -1387,7 +1383,7 @@ def findmodifiers(command): modset = set(command[:-len(realcommand)]) return realcommand, '@' in modset, '+' in modset, '-' in modset, '%' in modset -class _CommandWrapper(object): +class _CommandWrapper: def __init__(self, cline, ignoreErrors, loc, context, **kwargs): self.ignoreErrors = ignoreErrors self.loc = loc @@ -1397,7 +1393,7 @@ class _CommandWrapper(object): def _cb(self, res): if res != 0 and not self.ignoreErrors: - print "%s: command '%s' failed, return code %i" % (self.loc, self.cline, res) + print("%s: command '%s' failed, return code %i" % (self.loc, self.cline, res)) self.usercb(error=True) else: self.usercb(error=False) @@ -1412,7 +1408,7 @@ class _NativeWrapper(_CommandWrapper): _CommandWrapper.__init__(self, cline, ignoreErrors, loc, context, **kwargs) if pycommandpath: - self.pycommandpath = re.split('[%s\s]+' % os.pathsep, + self.pycommandpath = re.split(r'[%s\s]+' % os.pathsep, pycommandpath) else: self.pycommandpath = None @@ -1421,7 +1417,7 @@ class _NativeWrapper(_CommandWrapper): # get the module and method to call parts, badchar = process.clinetoargv(self.cline, self.kwargs['cwd']) if parts is None: - raise DataError("native command '%s': shell metacharacter '%s' in command line" % (self.cline, badchar), self.loc) + raise DataError("native command '{}': shell metacharacter '{}' in command line".format(self.cline, badchar), self.loc) if len(parts) < 2: raise DataError("native command '%s': no method name specified" % self.cline, self.loc) module = parts[0] @@ -1447,7 +1443,7 @@ def getcommandsforrule(rule, target, makefile, prerequisites, stem): if (isHidden or makefile.silent) and not makefile.justprint: echo = None else: - echo = "%s$ %s" % (c.loc, cline) + echo = "{}$ {}".format(c.loc, cline) if not isNative: yield _CommandWrapper(cline, ignoreErrors=ignoreErrors, env=env, cwd=makefile.workdir, loc=c.loc, context=makefile.context, echo=echo, justprint=makefile.justprint) @@ -1461,7 +1457,7 @@ def getcommandsforrule(rule, target, makefile, prerequisites, stem): echo=echo, justprint=makefile.justprint, pycommandpath=e) -class Rule(object): +class Rule: """ A rule contains a list of prerequisites and a list of commands. It may also contain rule-specific variables. This rule may be associated with multiple targets. @@ -1496,7 +1492,7 @@ class Rule(object): return getcommandsforrule(self, target, makefile, prereqs, stem=None) # TODO: $* in non-pattern rules? -class PatternRuleInstance(object): +class PatternRuleInstance: weakdeps = False """ @@ -1520,12 +1516,12 @@ class PatternRuleInstance(object): return getcommandsforrule(self, target, makefile, self.prerequisites, stem=self.dir + self.stem) def __str__(self): - return "Pattern rule at %s with stem '%s', matchany: %s doublecolon: %s" % (self.loc, + return "Pattern rule at {} with stem '{}', matchany: {} doublecolon: {}".format(self.loc, self.dir + self.stem, self.ismatchany, self.doublecolon) -class PatternRule(object): +class PatternRule: """ An implicit rule or static pattern rule containing target patterns, prerequisite patterns, and a list of commands. @@ -1543,7 +1539,7 @@ class PatternRule(object): self.commands.append(c) def ismatchany(self): - return util.any((t.ismatchany() for t in self.targetpatterns)) + return util.any(t.ismatchany() for t in self.targetpatterns) def hasspecificmatch(self, file): for p in self.targetpatterns: @@ -1577,7 +1573,7 @@ class PatternRule(object): def prerequisitesforstem(self, dir, stem): return [p.resolve(dir, stem) for p in self.prerequisites] -class _RemakeContext(object): +class _RemakeContext: def __init__(self, makefile, cb): self.makefile = makefile self.included = [(makefile.gettarget(f), required) @@ -1591,7 +1587,7 @@ class _RemakeContext(object): assert error in (True, False) if error and self.required: - print "Error remaking makefiles (ignored)" + print("Error remaking makefiles (ignored)") if len(self.toremake): target, self.required = self.toremake.pop(0) @@ -1608,7 +1604,7 @@ class _RemakeContext(object): self.cb(remade=False) -class Makefile(object): +class Makefile: """ The top-level data structure for makefile execution. It holds Targets, implicit rules, and other state data. @@ -1678,7 +1674,7 @@ class Makefile(object): self.variables.set('MAKECMDGOALS', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join(targets)) - for vname, val in implicit.variables.iteritems(): + for vname, val in implicit.variables.items(): self.variables.set(vname, Variables.FLAVOR_SIMPLE, Variables.SOURCE_IMPLICIT, val) @@ -1750,11 +1746,10 @@ class Makefile(object): if value is None: self._vpath = [] else: - self._vpath = filter(lambda e: e != '', - re.split('[%s\s]+' % os.pathsep, - value.resolvestr(self, self.variables, ['VPATH']))) + self._vpath = [e for e in re.split(r'[%s\s]+' % os.pathsep, + value.resolvestr(self, self.variables, ['VPATH'])) if e != ''] - targets = list(self._targets.itervalues()) + targets = list(self._targets.values()) for t in targets: t.explicit = True for r in t.rules: @@ -1825,7 +1820,7 @@ class Makefile(object): def getsubenvironment(self, variables): env = dict(self.env) - for vname, v in self.exportedvars.iteritems(): + for vname, v in self.exportedvars.items(): if v: flavor, source, val = variables.get(vname) if val is None: diff --git a/build/pymake/pymake/functions.py b/build/pymake/pymake/functions.py index e53fb54726..a8b738b638 100644 --- a/build/pymake/pymake/functions.py +++ b/build/pymake/pymake/functions.py @@ -19,12 +19,11 @@ def emit_expansions(descend, *expansions): for e, is_func in expansion: if is_func: - for exp in e.expansions(True): - yield exp + yield from e.expansions(True) else: yield e -class Function(object): +class Function: """ An object that represents a function call. This class is always subclassed with the following methods and attributes: @@ -51,7 +50,7 @@ class Function(object): argc = len(self._arguments) if argc < self.minargs: - raise data.DataError("Not enough arguments to function %s, requires %s" % (self.name, self.minargs), self.loc) + raise data.DataError("Not enough arguments to function {}, requires {}".format(self.name, self.minargs), self.loc) assert self.maxargs == 0 or argc <= self.maxargs, "Parser screwed up, gave us too many args" @@ -84,9 +83,9 @@ class Function(object): args.append(arg) if curly: - return '${%s %s}' % (self.name, ','.join(args)) + return '${{{} {}}}'.format(self.name, ','.join(args)) - return '$(%s %s)' % (self.name, ','.join(args)) + return '$({} {})'.format(self.name, ','.join(args)) def expansions(self, descend=False): """Obtain all expansions contained within this function. @@ -117,7 +116,7 @@ class Function(object): return len(self._arguments) def __repr__(self): - return "%s<%s>(%r)" % ( + return "{}<{}>({!r})".format( self.__class__.__name__, self.loc, ','.join([repr(a) for a in self._arguments]), ) @@ -160,7 +159,7 @@ class Function(object): return not self.__eq__(other) class VariableRef(Function): - AUTOMATIC_VARIABLES = set(['@', '%', '<', '?', '^', '+', '|', '*']) + AUTOMATIC_VARIABLES = {'@', '%', '<', '?', '^', '+', '|', '*'} __slots__ = ('vname', 'loc') @@ -175,11 +174,11 @@ class VariableRef(Function): def resolve(self, makefile, variables, fd, setting): vname = self.vname.resolvestr(makefile, variables, setting) if vname in setting: - raise data.DataError("Setting variable '%s' recursively references itself." % (vname,), self.loc) + raise data.DataError("Setting variable '{}' recursively references itself.".format(vname), self.loc) flavor, source, value = variables.get(vname) if value is None: - log.debug("%s: variable '%s' was not set" % (self.loc, vname)) + log.debug("{}: variable '{}' was not set".format(self.loc, vname)) return value.resolve(makefile, variables, fd, setting + [vname]) @@ -197,7 +196,7 @@ class VariableRef(Function): return emit_expansions(descend, self.vname) def __repr__(self): - return "VariableRef<%s>(%r)" % (self.loc, self.vname) + return "VariableRef<{}>({!r})".format(self.loc, self.vname) def __eq__(self, other): if not isinstance(other, VariableRef): @@ -222,14 +221,14 @@ class SubstitutionRef(Function): def resolve(self, makefile, variables, fd, setting): vname = self.vname.resolvestr(makefile, variables, setting) if vname in setting: - raise data.DataError("Setting variable '%s' recursively references itself." % (vname,), self.loc) + raise data.DataError("Setting variable '{}' recursively references itself.".format(vname), self.loc) substfrom = self.substfrom.resolvestr(makefile, variables, setting) substto = self.substto.resolvestr(makefile, variables, setting) flavor, source, value = variables.get(vname) if value is None: - log.debug("%s: variable '%s' was not set" % (self.loc, vname)) + log.debug("{}: variable '{}' was not set".format(self.loc, vname)) return f = data.Pattern(substfrom) @@ -241,7 +240,7 @@ class SubstitutionRef(Function): for word in value.resolvesplit(makefile, variables, setting + [vname])])) def to_source(self): - return '$(%s:%s=%s)' % ( + return '$({}:{}={})'.format( self.vname.to_source(), self.substfrom.to_source(), self.substto.to_source()) @@ -251,8 +250,8 @@ class SubstitutionRef(Function): self.substto) def __repr__(self): - return "SubstitutionRef<%s>(%r:%r=%r)" % ( - self.loc, self.vname, self.substfrom, self.substto,) + return "SubstitutionRef<{}>({!r}:{!r}={!r})".format( + self.loc, self.vname, self.substfrom, self.substto) def __eq__(self, other): if not isinstance(other, SubstitutionRef): @@ -325,7 +324,7 @@ class FilterFunction(Function): for p in self._arguments[0].resolvesplit(makefile, variables, setting)] fd.write(' '.join([w for w in self._arguments[1].resolvesplit(makefile, variables, setting) - if util.any((p.match(w) for p in plist))])) + if util.any(p.match(w) for p in plist)])) class FilteroutFunction(Function): name = 'filter-out' @@ -339,7 +338,7 @@ class FilteroutFunction(Function): for p in self._arguments[0].resolvesplit(makefile, variables, setting)] fd.write(' '.join([w for w in self._arguments[1].resolvesplit(makefile, variables, setting) - if not util.any((p.match(w) for p in plist))])) + if not util.any(p.match(w) for p in plist)])) class SortFunction(Function): name = 'sort' @@ -666,7 +665,7 @@ class CallFunction(Function): def resolve(self, makefile, variables, fd, setting): vname = self._arguments[0].resolvestr(makefile, variables, setting) if vname in setting: - raise data.DataError("Recursively setting variable '%s'" % (vname,)) + raise data.DataError("Recursively setting variable '{}'".format(vname)) v = data.Variables(parent=variables) v.set('0', data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, vname) @@ -680,7 +679,7 @@ class CallFunction(Function): return if flavor == data.Variables.FLAVOR_SIMPLE: - log.warning("%s: calling variable '%s' which is simply-expanded" % (self.loc, vname)) + log.warning("{}: calling variable '{}' which is simply-expanded".format(self.loc, vname)) # but we'll do it anyway e.resolve(makefile, v, fd, setting + [vname]) @@ -781,12 +780,12 @@ class ShellFunction(Function): if makefile.env is not None and 'PATH' in makefile.env: os.environ['PATH'] = makefile.env['PATH'] - log.debug("%s: running command '%s'" % (self.loc, ' '.join(cline))) + log.debug("{}: running command '{}'".format(self.loc, ' '.join(cline))) try: p = subprocess.Popen(cline, executable=executable, env=makefile.env, shell=False, stdout=subprocess.PIPE, cwd=makefile.workdir) - except OSError, e: - print >>sys.stderr, "Error executing command %s" % cline[0], e + except OSError as e: + print("Error executing command %s" % cline[0], e, file=sys.stderr) return finally: os.environ['PATH'] = oldpath @@ -830,7 +829,7 @@ class InfoFunction(Function): def resolve(self, makefile, variables, fd, setting): v = self._arguments[0].resolvestr(makefile, variables, setting) - print v + print(v) functionmap = { 'subst': SubstFunction, diff --git a/build/pymake/pymake/globrelative.py b/build/pymake/pymake/globrelative.py index 37ca28e068..3dbce4eb8a 100644 --- a/build/pymake/pymake/globrelative.py +++ b/build/pymake/pymake/globrelative.py @@ -7,7 +7,7 @@ Filename globbing like the python glob module with minor differences: """ import os, re, fnmatch -import util +from . import util _globcheck = re.compile('[[*?]') @@ -35,7 +35,7 @@ def glob(fsdir, path): if not os.path.isdir(fspath): continue - r.extend((util.normaljoin(dir, found) for found in globpattern(fspath, leaf))) + r.extend(util.normaljoin(dir, found) for found in globpattern(fspath, leaf)) return r @@ -62,7 +62,7 @@ def globpattern(dir, pattern): if not leaf.startswith('.')] leaves = fnmatch.filter(leaves, pattern) - leaves = filter(lambda l: os.path.exists(util.normaljoin(dir, l)), leaves) + leaves = [l for l in leaves if os.path.exists(util.normaljoin(dir, l))] leaves.sort() return leaves diff --git a/build/pymake/pymake/parser.py b/build/pymake/pymake/parser.py index 4bff533688..56e3be6ce7 100644 --- a/build/pymake/pymake/parser.py +++ b/build/pymake/pymake/parser.py @@ -34,15 +34,15 @@ coming. """ import logging, re, os, sys -import data, functions, util, parserdata +from . import data, functions, util, parserdata _log = logging.getLogger('pymake.parser') class SyntaxError(util.MakeError): pass -_skipws = re.compile('\S') -class Data(object): +_skipws = re.compile(r'\S') +class Data: """ A single virtual "line", which can be multiple source lines joined with continuations. @@ -108,7 +108,7 @@ _alltokens = re.compile(r'''\\*\# | # hash mark preceeded by any number of backs :: | (?:\$(?:$|[\(\{](?:%s)\s+|.)) | # dollar sign followed by EOF, a function keyword with whitespace, or any character :(?![\\/]) | # colon followed by anything except a slash (Windows path detection) - [=#{}();,|'"]''' % '|'.join(functions.functionmap.iterkeys()), re.VERBOSE) + [=#{}();,|'"]''' % '|'.join(functions.functionmap.keys()), re.VERBOSE) def iterdata(d, offset, tokenlist, it): """ @@ -233,7 +233,7 @@ def itercommandchars(d, offset, tokenlist, it): yield s[offset:d.lend].replace('\n\t', '\n'), None, None, None -_redefines = re.compile('\s*define|\s*endef') +_redefines = re.compile(r'\s*define|\s*endef') def iterdefinelines(it, startloc): """ Process the insides of a define. Most characters are included literally. Escaped newlines are treated @@ -336,7 +336,7 @@ _conditionkeywords = { 'ifndef': ifndef } -_conditiontokens = tuple(_conditionkeywords.iterkeys()) +_conditiontokens = tuple(_conditionkeywords.keys()) _conditionre = re.compile(r'(%s)(?:$|\s+)' % '|'.join(_conditiontokens)) _directivestokenlist = _conditiontokens + \ @@ -347,7 +347,7 @@ _directivesre = re.compile(r'(%s)(?:$|\s+)' % '|'.join(_directivestokenlist)) _varsettokens = (':=', '+=', '?=', '=') def _parsefile(pathname): - fd = open(pathname, "rU") + fd = open(pathname) stmts = parsestring(fd.read(), pathname) stmts.mtime = os.fstat(fd.fileno()).st_mtime fd.close() @@ -375,7 +375,7 @@ def parsefile(pathname): # colon followed by anything except a slash (Windows path detection) _depfilesplitter = re.compile(r':(?![\\/])') # simple variable references -_vars = re.compile('\$\((\w+)\)') +_vars = re.compile(r'\$\((\w+)\)') def parsedepfile(pathname): """ @@ -641,7 +641,7 @@ _PARSESTATE_SUBSTFROM = 3 # expanding a variable expansion substitution "from" _PARSESTATE_SUBSTTO = 4 # expanding a variable expansion substitution "to" value _PARSESTATE_PARENMATCH = 5 # inside nested parentheses/braces that must be matched -class ParseStackFrame(object): +class ParseStackFrame: __slots__ = ('parsestate', 'parent', 'expansion', 'tokenlist', 'openbrace', 'closebrace', 'function', 'loc', 'varname', 'substfrom') def __init__(self, parsestate, parent, expansion, tokenlist, openbrace, closebrace, function=None, loc=None): @@ -691,7 +691,7 @@ def parsemakesyntax(d, offset, stopon, iterfunc): while True: # this is not a for loop because `di` changes during the function assert stacktop is not None try: - s, token, tokenoffset, offset = di.next() + s, token, tokenoffset, offset = next(di) except StopIteration: break diff --git a/build/pymake/pymake/parserdata.py b/build/pymake/pymake/parserdata.py index 7b2e5443d5..e1368c237e 100644 --- a/build/pymake/pymake/parserdata.py +++ b/build/pymake/pymake/parserdata.py @@ -1,12 +1,12 @@ import logging, re, os -import data, parser, functions, util +from . import data, parser, functions, util from cStringIO import StringIO from pymake.globrelative import hasglob, glob _log = logging.getLogger('pymake.data') _tabwidth = 4 -class Location(object): +class Location: """ A location within a makefile. @@ -54,7 +54,7 @@ class Location(object): return Location(self.path, line, column) def __str__(self): - return "%s:%s:%s" % (self.path, self.line, self.column) + return "{}:{}:{}".format(self.path, self.line, self.column) def _expandwildcards(makefile, tlist): for t in tlist: @@ -62,8 +62,7 @@ def _expandwildcards(makefile, tlist): yield t else: l = glob(makefile.workdir, t) - for r in l: - yield r + yield from l _flagescape = re.compile(r'([\s\\])') @@ -76,7 +75,7 @@ def parsecommandlineargs(args): overrides = [] stmts = StatementList() r = [] - for i in xrange(0, len(args)): + for i in range(0, len(args)): a = args[i] vname, t, val = util.strpartition(a, ':=') @@ -97,7 +96,7 @@ def parsecommandlineargs(args): return stmts, r, ' '.join(overrides) -class Statement(object): +class Statement: """ Represents parsed make file syntax. @@ -123,7 +122,7 @@ class Statement(object): def __ne__(self, other): return self.__eq__(other) -class DummyRule(object): +class DummyRule: __slots__ = () def addcommand(self, r): @@ -188,14 +187,14 @@ class Rule(Statement): context.currule = DummyRule() return - ispatterns = set((t.ispattern() for t in targets)) + ispatterns = {t.ispattern() for t in targets} if len(ispatterns) == 2: raise data.DataError("Mixed implicit and normal rule", self.targetexp.loc) ispattern, = ispatterns deps = list(_expandwildcards(makefile, data.stripdotslashes(self.depexp.resolvesplit(makefile, makefile.variables)))) if ispattern: - rule = data.PatternRule(targets, map(data.Pattern, deps), self.doublecolon, loc=self.targetexp.loc) + rule = data.PatternRule(targets, list(map(data.Pattern, deps)), self.doublecolon, loc=self.targetexp.loc) makefile.appendimplicitrule(rule) else: rule = data.Rule(deps, self.doublecolon, loc=self.targetexp.loc, weakdeps=False) @@ -207,7 +206,7 @@ class Rule(Statement): context.currule = rule def dump(self, fd, indent): - print >>fd, "%sRule %s: %s" % (indent, self.targetexp, self.depexp) + print("{}Rule {}: {}".format(indent, self.targetexp, self.depexp, file=fd)) def to_source(self): sep = ':' @@ -219,7 +218,7 @@ class Rule(Statement): if len(deps) > 0 and not deps[0].isspace(): sep += ' ' - return '\n%s%s%s' % ( + return '\n{}{}{}'.format( self.targetexp.to_source(escape_variables=True), sep, deps) @@ -275,17 +274,17 @@ class StaticPatternRule(Statement): for t in targets: if data.Pattern(t).ispattern(): - raise data.DataError("Target '%s' of a static pattern rule must not be a pattern" % (t,), self.targetexp.loc) + raise data.DataError("Target '{}' of a static pattern rule must not be a pattern".format(t), self.targetexp.loc) stem = pattern.match(t) if stem is None: - raise data.DataError("Target '%s' does not match the static pattern '%s'" % (t, pattern), self.targetexp.loc) + raise data.DataError("Target '{}' does not match the static pattern '{}'".format(t, pattern), self.targetexp.loc) makefile.gettarget(t).addrule(data.PatternRuleInstance(rule, '', stem, pattern.ismatchany())) makefile.foundtarget(targets[0]) context.currule = rule def dump(self, fd, indent): - print >>fd, "%sStaticPatternRule %s: %s: %s" % (indent, self.targetexp, self.patternexp, self.depexp) + print("{}StaticPatternRule {}: {}: {}".format(indent, self.targetexp, self.patternexp, self.depexp, file=fd)) def to_source(self): sep = ':' @@ -299,7 +298,7 @@ class StaticPatternRule(Statement): if len(pattern) > 0 and pattern[0] not in (' ', '\t'): sep += ' ' - return '\n%s%s%s:%s' % ( + return '\n{}{}{}:{}'.format( self.targetexp.to_source(escape_variables=True), sep, pattern, @@ -339,7 +338,7 @@ class Command(Statement): context.currule.addcommand(self.exp) def dump(self, fd, indent): - print >>fd, "%sCommand %s" % (indent, self.exp,) + print("{}Command {}".format(indent, self.exp, file=fd)) def to_source(self): # Commands have some interesting quirks when it comes to source @@ -438,7 +437,7 @@ class SetVariable(Statement): v.set(vname, flavor, self.source, value) def dump(self, fd, indent): - print >>fd, "%sSetVariable<%s> %s %s\n%s %r" % (indent, self.valueloc, self.vnameexp, self.token, indent, self.value) + print("{}SetVariable<{}> {} {}\n{} {!r}".format(indent, self.valueloc, self.vnameexp, self.token, indent, self.value, file=fd)) def __eq__(self, other): if not isinstance(other, SetVariable): @@ -452,7 +451,7 @@ class SetVariable(Statement): def to_source(self): chars = [] - for i in xrange(0, len(self.value)): + for i in range(0, len(self.value)): c = self.value[i] # Literal # is escaped in variable assignment otherwise it would be @@ -477,7 +476,7 @@ class SetVariable(Statement): # We handle the target-specific syntax first. if self.targetexp is not None: - return '%s: %s %s %s' % ( + return '{}: {} {} {}'.format( self.targetexp.to_source(), self.vnameexp.to_source(), self.token, @@ -489,18 +488,18 @@ class SetVariable(Statement): # the variable must have come from a define. if value.count('\n') > 0 or (len(value) and value[0].isspace()): # The parser holds the token in vnameexp for whatever reason. - return '%sdefine %s\n%s\nendef' % ( + return '{}define {}\n{}\nendef'.format( prefix, self.vnameexp.to_source(), value) - return '%s%s %s %s' % ( + return '{}{} {} {}'.format( prefix, self.vnameexp.to_source(), self.token, value) -class Condition(object): +class Condition: """ An abstract "condition", either ifeq or ifdef, perhaps negated. @@ -543,7 +542,7 @@ class EqCondition(Condition): return (r1 == r2) == self.expected def __str__(self): - return "ifeq (expected=%s) %s %s" % (self.expected, self.exp1, self.exp2) + return "ifeq (expected={}) {} {}".format(self.expected, self.exp1, self.exp2) def __eq__(self, other): if not isinstance(other, EqCondition): @@ -580,7 +579,7 @@ class IfdefCondition(Condition): return (len(value) > 0) == self.expected def __str__(self): - return "ifdef (expected=%s) %s" % (self.expected, self.exp) + return "ifdef (expected={}) {}".format(self.expected, self.exp) def __eq__(self, other): if not isinstance(other, IfdefCondition): @@ -651,14 +650,14 @@ class ConditionBlock(Statement): i += 1 def dump(self, fd, indent): - print >>fd, "%sConditionBlock" % (indent,) + print("{}ConditionBlock".format(indent, file=fd)) indent2 = indent + ' ' for c, statements in self._groups: - print >>fd, "%s Condition %s" % (indent, c) + print("{} Condition {}".format(indent, c, file=fd)) statements.dump(fd, indent2) - print >>fd, "%s ~Condition" % (indent,) - print >>fd, "%s~ConditionBlock" % (indent,) + print("{} ~Condition".format(indent, file=fd)) + print("{}~ConditionBlock".format(indent, file=fd)) def to_source(self): lines = [] @@ -681,7 +680,7 @@ class ConditionBlock(Statement): if len(self) != len(other): return False - for i in xrange(0, len(self)): + for i in range(0, len(self)): our_condition, our_statements = self[i] other_condition, other_statements = other[i] @@ -709,9 +708,9 @@ class ConditionBlock(Statement): s = statement.exp.s if statement.expected: - return '%sifdef %s' % (prefix, s) + return '{}ifdef {}'.format(prefix, s) - return '%sifndef %s' % (prefix, s) + return '{}ifndef {}'.format(prefix, s) if isinstance(statement, EqCondition): args = [ @@ -750,9 +749,9 @@ class ConditionBlock(Statement): body = '(%s)' % ','.join(args) if statement.expected: - return '%sifeq %s' % (prefix, body) + return '{}ifeq {}'.format(prefix, body) - return '%sifneq %s' % (prefix, body) + return '{}ifneq {}'.format(prefix, body) if isinstance(statement, ElseCondition): return 'else' @@ -793,7 +792,7 @@ class Include(Statement): makefile.include(f, self.required, loc=self.exp.loc, weak=self.weak) def dump(self, fd, indent): - print >>fd, "%sInclude %s" % (indent, self.exp) + print("{}Include {}".format(indent, self.exp, file=fd)) def to_source(self): prefix = '' @@ -801,7 +800,7 @@ class Include(Statement): if not self.required: prefix = '-' - return '%sinclude %s' % (prefix, self.exp.to_source()) + return '{}include {}'.format(prefix, self.exp.to_source()) def __eq__(self, other): if not isinstance(other, Include): @@ -834,13 +833,13 @@ class VPathDirective(Statement): else: dirs = [] for mpath in mpaths: - dirs.extend((dir for dir in mpath.split(os.pathsep) - if dir != '')) + dirs.extend(dir for dir in mpath.split(os.pathsep) + if dir != '') if len(dirs): makefile.addvpath(pattern, dirs) def dump(self, fd, indent): - print >>fd, "%sVPath %s" % (indent, self.exp) + print("{}VPath {}".format(indent, self.exp, file=fd)) def to_source(self): return 'vpath %s' % self.exp.to_source() @@ -885,7 +884,7 @@ class ExportDirective(Statement): makefile.exportedvars[v] = True def dump(self, fd, indent): - print >>fd, "%sExport (single=%s) %s" % (indent, self.single, self.exp) + print("{}Export (single={}, file=fd) {}".format(indent, self.single, self.exp)) def to_source(self): return ('export %s' % self.exp.to_source()).rstrip() @@ -915,7 +914,7 @@ class UnexportDirective(Statement): makefile.exportedvars[v] = False def dump(self, fd, indent): - print >>fd, "%sUnexport %s" % (indent, self.exp) + print("{}Unexport {}".format(indent, self.exp, file=fd)) def to_source(self): return 'unexport %s' % self.exp.to_source() @@ -947,7 +946,7 @@ class EmptyDirective(Statement): raise data.DataError("Line expands to non-empty value", self.exp.loc) def dump(self, fd, indent): - print >>fd, "%sEmptyDirective: %s" % (indent, self.exp) + print("{}EmptyDirective: {}".format(indent, self.exp, file=fd)) def to_source(self): return self.exp.to_source() @@ -958,7 +957,7 @@ class EmptyDirective(Statement): return self.exp == other.exp -class _EvalContext(object): +class _EvalContext: __slots__ = ('currule', 'weak') def __init__(self, weak): @@ -1003,4 +1002,4 @@ def iterstatements(stmts): yield s if isinstance(s, ConditionBlock): for c, sl in s: - for s2 in iterstatments(sl): yield s2 + yield from iterstatments(sl) diff --git a/build/pymake/pymake/process.py b/build/pymake/pymake/process.py index 01cadf5a99..f78d1f35e4 100644 --- a/build/pymake/pymake/process.py +++ b/build/pymake/pymake/process.py @@ -45,7 +45,7 @@ _unquoted_tokens = tokens2re({ _doubly_quoted_tokens = tokens2re({ 'quote': '"', 'backslashedquote': r'\\"', - 'special': '\$', + 'special': r'\$', 'backslashed': r'\\[^\\"]', }) @@ -129,7 +129,7 @@ class ClineSplitter(list): elif 'special' in match: # Unquoted, non-escaped special characters need to be sent to a # shell. - raise MetaCharacterException, match['special'] + raise MetaCharacterException(match['special']) elif 'whitespace' in match: # Whitespaces terminate current argument. self._next() @@ -145,7 +145,7 @@ class ClineSplitter(list): self.glob = True self._push(m.group(0)) else: - raise Exception, "Shouldn't reach here" + raise Exception("Shouldn't reach here") if self.arg: self._next() @@ -153,17 +153,17 @@ class ClineSplitter(list): # Single quoted strings are preserved, except for the final quote index = self.cline.find("'") if index == -1: - raise Exception, 'Unterminated quoted string in command' + raise Exception('Unterminated quoted string in command') self._push(self.cline[:index]) self.cline = self.cline[index+1:] def _parse_doubly_quoted(self): if not self.cline: - raise Exception, 'Unterminated quoted string in command' + raise Exception('Unterminated quoted string in command') while self.cline: m = _doubly_quoted_tokens.search(self.cline) if not m: - raise Exception, 'Unterminated quoted string in command' + raise Exception('Unterminated quoted string in command') self._push(self.cline[:m.start()]) self.cline = self.cline[m.end():] match = dict([(name, value) for name, value in m.groupdict().items() if value]) @@ -175,7 +175,7 @@ class ClineSplitter(list): # Unquoted, non-escaped special characters in a doubly quoted # string still have a special meaning and need to be sent to a # shell. - raise MetaCharacterException, match['special'] + raise MetaCharacterException(match['special']) elif 'escape' in match: # Escaped backslashes turn into a single backslash self._push('\\') @@ -194,7 +194,7 @@ def clinetoargv(cline, cwd): str = _escapednewlines.sub('', cline) try: args = ClineSplitter(str, cwd) - except MetaCharacterException, e: + except MetaCharacterException as e: return None, e.char if len(args) and args[0].find('=') != -1: @@ -331,8 +331,8 @@ class PopenJob(Job): os.environ['PATH'] = self.env['PATH'] p = subprocess.Popen(self.argv, executable=self.executable, shell=self.shell, env=self.env, cwd=self.cwd) return p.wait() - except OSError, e: - print >>sys.stderr, e + except OSError as e: + print(e, file=sys.stderr) return -127 finally: os.environ['PATH'] = oldpath @@ -383,30 +383,30 @@ class PythonJob(Job): try: __import__(self.module) except Exception as e: - print >>sys.stderr, 'Error importing %s: %s' % ( + print('Error importing %s: %s' % (, file=sys.stderr) self.module, e) return -127 m = sys.modules[self.module] if self.method not in m.__dict__: - print >>sys.stderr, "No method named '%s' in module %s" % (self.method, self.module) + print("No method named '%s' in module %s" % (self.method, self.module), file=sys.stderr) return -127 rv = m.__dict__[self.method](self.argv) if rv != 0 and rv is not None: - print >>sys.stderr, ( + print((, file=sys.stderr) "Native command '%s %s' returned value '%s'" % (self.module, self.method, rv)) return (rv if isinstance(rv, int) else 1) - except PythonException, e: - print >>sys.stderr, e + except PythonException as e: + print(e, file=sys.stderr) return e.exitcode except: e = sys.exc_info()[1] if isinstance(e, SystemExit) and (e.code == 0 or e.code is None): pass # sys.exit(0) is not a failure else: - print >>sys.stderr, e + print(e, file=sys.stderr) traceback.print_exc() return -127 finally: @@ -461,7 +461,7 @@ class ParallelContext(object): def _docall_generic(self, pool, job, cb, echo, justprint): if echo is not None: - print echo + print(echo) processcb = job.get_callback(ParallelContext._condition) if justprint: processcb(0) @@ -525,7 +525,7 @@ class ParallelContext(object): for c in clist: c.run() - dowait = util.any((len(c.running) for c in ParallelContext._allcontexts)) + dowait = util.any(len(c.running) for c in ParallelContext._allcontexts) if dowait: # Wait on local jobs first for perf for job, cb in ParallelContext._waitany(ParallelContext._condition): diff --git a/build/pymake/pymake/util.py b/build/pymake/pymake/util.py index c63f930cc2..d3f193e54a 100644 --- a/build/pymake/pymake/util.py +++ b/build/pymake/pymake/util.py @@ -8,9 +8,9 @@ class MakeError(Exception): def __str__(self): locstr = '' if self.loc is not None: - locstr = "%s:" % (self.loc,) + locstr = "{}:".format(self.loc) - return "%s%s" % (locstr, self.msg) + return "{}{}".format(locstr, self.msg) def normaljoin(path, suffix): """ @@ -82,7 +82,7 @@ else: return str[:offset], token, str[offset + len(token):] try: - from __builtin__ import any + from builtins import any except ImportError: def any(it): for i in it: @@ -90,7 +90,7 @@ except ImportError: return True return False -class _MostUsedItem(object): +class _MostUsedItem: __slots__ = ('key', 'o', 'count') def __init__(self, key): @@ -101,7 +101,7 @@ class _MostUsedItem(object): def __repr__(self): return "MostUsedItem(key=%r, count=%i, o=%r)" % (self.key, self.count, self.o) -class MostUsedCache(object): +class MostUsedCache: def __init__(self, capacity, creationfunc, verifyfunc): self.capacity = capacity self.cfunc = creationfunc @@ -138,7 +138,7 @@ class MostUsedCache(object): return item.o def verify(self): - for k, v in self.d.iteritems(): + for k, v in self.d.items(): if v.o: assert v in self.active else: diff --git a/build/pymake/tests/datatests.py b/build/pymake/tests/datatests.py index 513028b0b2..f42efbf6ee 100644 --- a/build/pymake/tests/datatests.py +++ b/build/pymake/tests/datatests.py @@ -4,7 +4,7 @@ import re from cStringIO import StringIO def multitest(cls): - for name in cls.testdata.iterkeys(): + for name in cls.testdata.keys(): def m(self, name=name): return self.runSingle(*self.testdata[name]) @@ -20,7 +20,7 @@ class SplitWordsTest(unittest.TestCase): def runTest(self): for s, e in self.testdata: w = s.split() - self.assertEqual(w, e, 'splitwords(%r)' % (s,)) + self.assertEqual(w, e, 'splitwords({!r})'.format(s)) class GetPatSubstTest(unittest.TestCase): testdata = ( @@ -37,9 +37,9 @@ class GetPatSubstTest(unittest.TestCase): for s, r, d, e in self.testdata: words = d.split() p = pymake.data.Pattern(s) - a = ' '.join((p.subst(r, word, False) - for word in words)) - self.assertEqual(a, e, 'Pattern(%r).subst(%r, %r)' % (s, r, d)) + a = ' '.join(p.subst(r, word, False) + for word in words) + self.assertEqual(a, e, 'Pattern({!r}).subst({!r}, {!r})'.format(s, r, d)) class LRUTest(unittest.TestCase): # getkey, expected, funccount, debugitems @@ -63,7 +63,7 @@ class LRUTest(unittest.TestCase): c = pymake.util.LRUCache(3, self.spaceFunc, lambda k, v: k % 2) self.assertEqual(tuple(c.debugitems()), ()) - for i in xrange(0, len(self.expected)): + for i in range(0, len(self.expected)): k, e, fc, di = self.expected[i] v = c.get(k) diff --git a/build/pymake/tests/formattingtests.py b/build/pymake/tests/formattingtests.py index 7aad6d4cc1..2ab203a9ae 100644 --- a/build/pymake/tests/formattingtests.py +++ b/build/pymake/tests/formattingtests.py @@ -94,7 +94,7 @@ class StringExpansionTest(TestBase): e = StringExpansion('this is # not a comment', None) self.assertEqual(e.to_source(escape_comments=True), - 'this is \# not a comment') + r'this is \# not a comment') def test_empty(self): e = StringExpansion('', None) @@ -253,7 +253,7 @@ class MakefileCorupusTest(TestBase): continue source = None - with open(makefile, 'rU') as fh: + with open(makefile) as fh: source = fh.read() try: @@ -277,7 +277,7 @@ class MakefileCorupusTest(TestBase): self.assertEqual(len(statements), len(new_statements)) - for i in xrange(0, len(statements)): + for i in range(0, len(statements)): original = statements[i] formatted = new_statements[i] diff --git a/build/pymake/tests/parsertests.py b/build/pymake/tests/parsertests.py index ab6406be0f..0f6487fe5a 100644 --- a/build/pymake/tests/parsertests.py +++ b/build/pymake/tests/parsertests.py @@ -5,7 +5,7 @@ import logging from cStringIO import StringIO def multitest(cls): - for name in cls.testdata.iterkeys(): + for name in cls.testdata.keys(): def m(self, name=name): return self.runSingle(*self.testdata[name]) @@ -15,7 +15,7 @@ def multitest(cls): class TestBase(unittest.TestCase): def assertEqual(self, a, b, msg=""): """Actually print the values which weren't equal, if things don't work out!""" - unittest.TestCase.assertEqual(self, a, b, "%s got %r expected %r" % (msg, a, b)) + unittest.TestCase.assertEqual(self, a, b, "{} got {!r} expected {!r}".format(msg, a, b)) class DataTest(TestBase): testdata = { @@ -86,7 +86,7 @@ class IterTest(TestBase): ), 'makeescapedcomment': ( pymake.parser.itermakefilechars, - "VAR = val \# escaped hash", + r"VAR = val \# escaped hash", "VAR = val # escaped hash" ), 'makeescapedslash': ( @@ -116,8 +116,8 @@ class IterTest(TestBase): ), 'commandcomment': ( pymake.parser.itercommandchars, - "echo boo \# comment", - "echo boo \# comment", + r"echo boo \# comment", + r"echo boo \# comment", ), 'commandcontinue': ( pymake.parser.itercommandchars, @@ -134,7 +134,7 @@ class IterTest(TestBase): self.assertEqual(actual, expected) if ifunc == pymake.parser.itermakefilechars: - print "testing %r" % expected + print("testing %r" % expected) self.assertEqual(pymake.parser.flattenmakesyntax(d, 0), expected) multitest(IterTest) @@ -206,18 +206,18 @@ class MakeSyntaxTest(TestBase): def compareRecursive(self, actual, expected, path): self.assertEqual(len(actual), len(expected), - "compareRecursive: %s %r" % (path, actual)) - for i in xrange(0, len(actual)): + "compareRecursive: {} {!r}".format(path, actual)) + for i in range(0, len(actual)): ipath = path + [i] a, isfunc = actual[i] e = expected[i] if isinstance(e, str): - self.assertEqual(a, e, "compareRecursive: %s" % (ipath,)) + self.assertEqual(a, e, "compareRecursive: {}".format(ipath)) else: self.assertEqual(type(a), getattr(pymake.functions, e['type']), - "compareRecursive: %s" % (ipath,)) - for k, v in e.iteritems(): + "compareRecursive: {}".format(ipath)) + for k, v in e.items(): if k == 'type': pass elif k[0] == '[': @@ -229,7 +229,7 @@ class MakeSyntaxTest(TestBase): proppath = ipath + [item] self.compareRecursive(getattr(a, item), v, proppath) else: - raise Exception("Unexpected property at %s: %s" % (ipath, k)) + raise Exception("Unexpected property at {}: {}".format(ipath, k)) def runSingle(self, s, startat, stopat, stopoffset, expansion): d = pymake.parser.Data.fromstring(s, pymake.parserdata.Location('testdata', 1, 0)) @@ -264,7 +264,7 @@ class VariableTest(TestBase): m = pymake.data.Makefile() stmts.execute(m) - for k, v in self.expected.iteritems(): + for k, v in self.expected.items(): flavor, source, val = m.variables.get(k) if val is None: self.assertEqual(val, v, 'variable named %s' % k) diff --git a/build/pymake/tests/runtests.py b/build/pymake/tests/runtests.py index ab149ecfb1..6ea0b91a97 100644 --- a/build/pymake/tests/runtests.py +++ b/build/pymake/tests/runtests.py @@ -78,15 +78,15 @@ def runTest(makefile, make, logfile, options): logfd.close() if stdout.find('TEST-FAIL') != -1: - print stdout + print(stdout) return False, "FAIL (TEST-FAIL printed)" if options['grepfor'] and stdout.find(options['grepfor']) == -1: - print stdout + print(stdout) return False, "FAIL (%s not in output)" % options['grepfor'] if options['returncode'] == 0 and stdout.find('TEST-PASS') == -1: - print stdout + print(stdout) return False, 'FAIL (No TEST-PASS printed)' if options['returncode'] != 0: @@ -94,7 +94,7 @@ def runTest(makefile, make, logfile, options): return True, 'PASS' -print "%-30s%-28s%-28s" % ("Test:", "gmake:", "pymake:") +print("%-30s%-28s%-28s" % ("Test:", "gmake:", "pymake:")) gmakefails = 0 pymakefails = 0 @@ -153,7 +153,7 @@ for makefile in makefiles: elif key == 'skip': d['skip'] = True else: - print >>sys.stderr, "%s: Unexpected #T key: %s" % (makefile, key) + print("%s: Unexpected #T key: %s" % (makefile, key), file=sys.stderr) sys.exit(1) mdata.close() @@ -190,12 +190,11 @@ for makefile in makefiles: else: pymakemsg = "OK (known fail)" - print "%-30.30s%-28.28s%-28.28s" % (os.path.basename(makefile), + print("%-30.30s%-28.28s%-28.28s" % (os.path.basename(makefile),) gmakemsg, pymakemsg) -print -print "Summary:" -print "%-30s%-28s%-28s" % ("", "gmake:", "pymake:") +print(print "Summary:") +print("%-30s%-28s%-28s" % ("", "gmake:", "pymake:")) if gmakefails == 0: gmakemsg = 'PASS' @@ -207,7 +206,7 @@ if pymakefails == 0: else: pymakemsg = 'FAIL (%i failures)' % pymakefails -print "%-30.30s%-28.28s%-28.28s" % ('', gmakemsg, pymakemsg) +print("%-30.30s%-28.28s%-28.28s" % ('', gmakemsg, pymakemsg)) shutil.rmtree(opts.tempdir) diff --git a/build/release/info.py b/build/release/info.py index 7e7a30bcea..c3c3ec9921 100644 --- a/build/release/info.py +++ b/build/release/info.py @@ -4,7 +4,7 @@ from os import path import re import shutil import sys -from urllib2 import urlopen +from urllib.request import urlopen from release.paths import makeCandidatesDir @@ -13,7 +13,7 @@ log = logging.getLogger(__name__) # If version has two parts with no trailing specifiers like "rc", we # consider it a "final" release for which we only create a _RELEASE tag. -FINAL_RELEASE_REGEX = "^\d+\.\d+$" +FINAL_RELEASE_REGEX = r"^\d+\.\d+$" class ConfigError(Exception): @@ -50,7 +50,7 @@ def findOldBuildIDs(product, version, buildNumber, platforms, id = getBuildID(platform, product, version, n, nightlyDir, server) ids[platform].append(id) - except Exception, e: + except Exception as e: log.error("Hit exception: %s" % e) return ids @@ -62,7 +62,7 @@ def getReleaseConfigName(product, branch, version=None, staging=False): if product == 'thunderbird' and 'esr17' in branch and version and 'esr' not in version: cfg = 'release-thunderbird-comm-release.py' else: - cfg = 'release-%s-%s.py' % (product, branch) + cfg = 'release-{}-{}.py'.format(product, branch) if staging: cfg = 'staging_%s' % cfg return cfg @@ -87,15 +87,15 @@ def readBranchConfig(dir, localconfig, branch, required=[]): def readConfig(configfile, keys=[], required=[]): c = {} - execfile(configfile, c) + exec(compile(open(configfile, "rb").read(), configfile, 'exec'), c) for k in keys: c = c[k] - items = c.keys() + items = list(c.keys()) err = False for key in required: if key not in items: err = True - log.error("Required item `%s' missing from %s" % (key, c)) + log.error("Required item `{}' missing from {}".format(key, c)) if err: raise ConfigError("Missing at least one item in config, see above") return c @@ -108,7 +108,7 @@ def isFinalRelease(version): def getBaseTag(product, version): product = product.upper() version = version.replace('.', '_') - return '%s_%s' % (product, version) + return '{}_{}'.format(product, version) def getTags(baseTag, buildNumber, buildTag=True): @@ -127,13 +127,13 @@ def getReleaseTag(tag): def generateRelbranchName(version, prefix='GECKO'): - return '%s%s_%s_RELBRANCH' % ( + return '{}{}_{}_RELBRANCH'.format( prefix, version.replace('.', ''), datetime.utcnow().strftime('%Y%m%d%H')) def getReleaseName(product, version, buildNumber): - return '%s-%s-build%s' % (product.title(), version, str(buildNumber)) + return '{}-{}-build{}'.format(product.title(), version, str(buildNumber)) def getRepoMatchingBranch(branch, sourceRepositories): @@ -161,7 +161,7 @@ def fileInfo(filepath, product): # Mozilla 1.9.0 style (aka 'short') paths # e.g. firefox-3.0.12.en-US.win32.complete.mar filename = os.path.basename(filepath) - m = re.match("^(%s)-([0-9.]+)\.([-a-zA-Z]+)\.(win32)\.(complete|installer)\.(mar|exe)$" % product, filename) + m = re.match(r"^(%s)-([0-9.]+)\.([-a-zA-Z]+)\.(win32)\.(complete|installer)\.(mar|exe)$" % product, filename) if not m: raise ValueError("Could not parse: %s" % filename) return {'product': m.group(1), @@ -180,7 +180,7 @@ def fileInfo(filepath, product): ret = {'pathstyle': 'long'} if filepath.endswith('.mar'): ret['format'] = 'mar' - m = re.search("update/(win32|linux-i686|linux-x86_64|mac|mac64)/([-a-zA-Z]+)/(%s)-(\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?)\.(complete)\.mar" % product, filepath) + m = re.search(r"update/(win32|linux-i686|linux-x86_64|mac|mac64)/([-a-zA-Z]+)/(%s)-(\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?)\.(complete)\.mar" % product, filepath) if not m: raise ValueError("Could not parse: %s" % filepath) ret['platform'] = m.group(1) @@ -196,7 +196,7 @@ def fileInfo(filepath, product): # that we can't catch them in the same regexp if filepath.find('win32-EUballot') != -1: ret['platform'] = 'win32' - m = re.search("(win32-EUballot/)([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+\d+)?(?:\ \w+\ \d+)?)\.exe" % product, filepath) + m = re.search(r"(win32-EUballot/)([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+\d+)?(?:\ \w+\ \d+)?)\.exe" % product, filepath) if not m: raise ValueError("Could not parse: %s" % filepath) ret['leading_path'] = m.group(1) @@ -204,7 +204,7 @@ def fileInfo(filepath, product): ret['product'] = m.group(3).lower() ret['version'] = m.group(4) else: - m = re.search("(partner-repacks/[-a-zA-Z0-9_]+/|)(win32|mac|linux-i686)/([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?(?:\ \w+\ \d+)?)\.exe" % product, filepath) + m = re.search(r"(partner-repacks/[-a-zA-Z0-9_]+/|)(win32|mac|linux-i686)/([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?(?:\ \w+\ \d+)?)\.exe" % product, filepath) if not m: raise ValueError("Could not parse: %s" % filepath) ret['leading_path'] = m.group(1) diff --git a/build/release/sanity.py b/build/release/sanity.py index aba8559894..70d745f471 100644 --- a/build/release/sanity.py +++ b/build/release/sanity.py @@ -1,10 +1,11 @@ import difflib import logging import re -import urllib2 +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse from util.commands import run_cmd, get_output from util.hg import get_repo_name, make_hg_url from subprocess import CalledProcessError +import six log = logging.getLogger(__name__) @@ -44,7 +45,7 @@ def get_buildbot_username_param(): def sendchange(branch, revision, username, master, products): """Send the change to buildbot to kick off the release automation""" - if isinstance(products, basestring): + if isinstance(products, str): products = [products] cmd = [ 'buildbot', @@ -107,7 +108,7 @@ def verify_mozconfigs(mozconfig_pair, nightly_mozconfig_pair, platform, mozconfigWhitelist['nightly'][platform]: continue else: - log.warning("%s not in %s %s!" % ( + log.warning("{} not in {} {}!".format( clean_line, platform, mozconfigWhitelist['nightly'][platform])) else: diff --git a/build/subconfigure.py b/build/subconfigure.py index 6c152f4065..4e54a9a268 100644 --- a/build/subconfigure.py +++ b/build/subconfigure.py @@ -131,11 +131,11 @@ def maybe_clear_cache(data): is_set = cache.get('ac_cv_env_%s_set' % precious) == 'set' value = cache.get('ac_cv_env_%s_value' % precious) if is_set else None if value != env.get(precious): - print 'Removing %s because of %s value change from:' \ - % (data['cache-file'], precious) - print ' %s' % (value if value is not None else 'undefined') - print 'to:' - print ' %s' % env.get(precious, 'undefined') + print('Removing %s because of %s value change from:' + % (data['cache-file'], precious)) + print(' %s' % (value if value is not None else 'undefined')) + print('to:') + print(' %s' % env.get(precious, 'undefined')) os.remove(data['cache-file']) return True return False @@ -199,9 +199,12 @@ def prepare(srcdir, objdir, shell, args): data_file = os.path.join(objdir, CONFIGURE_DATA) previous_args = None if os.path.exists(data_file): - with open(data_file, 'rb') as f: - data = pickle.load(f) - previous_args = data['args'] + try: + with open(data_file, 'rb') as f: + data = pickle.load(f) + previous_args = data['args'] + except (EOFError, pickle.UnpicklingError): + pass # Msys likes to break environment variables and command line arguments, # so read those from stdin, as they are passed from the configure script @@ -221,7 +224,7 @@ def prepare(srcdir, objdir, shell, args): environ[var] = os.environ[var] args = data['args'] else: - environ = os.environ + environ = dict(os.environ) args, others = parser.parse_known_args(args) @@ -333,14 +336,20 @@ def run(objdir): # We're going to run it ourselves. command += ['--no-create'] - print prefix_lines('configuring', relobjdir) - print prefix_lines('running %s' % ' '.join(command[:-1]), relobjdir) + print(prefix_lines('configuring', relobjdir)) + print(prefix_lines('running %s' % ' '.join(command[:-1]), relobjdir)) sys.stdout.flush() try: - output += subprocess.check_output(command, + cmd_out = subprocess.check_output(command, stderr=subprocess.STDOUT, cwd=objdir, env=data['env']) + if isinstance(cmd_out, bytes): + cmd_out = cmd_out.decode('utf-8', errors='replace') + output += cmd_out except subprocess.CalledProcessError as e: - return relobjdir, e.returncode, e.output + err_out = e.output + if isinstance(err_out, bytes): + err_out = err_out.decode('utf-8', errors='replace') + return relobjdir, e.returncode, err_out # Leave config.status with a new timestamp if configure is newer than # its original mtime. @@ -368,15 +377,21 @@ def run(objdir): if not skip_config_status: if skip_configure: - print prefix_lines('running config.status', relobjdir) + print(prefix_lines('running config.status', relobjdir)) sys.stdout.flush() try: - output += subprocess.check_output([data['shell'], '-c', + cs_out = subprocess.check_output([data['shell'], '-c', './config.status'], stderr=subprocess.STDOUT, cwd=objdir, env=data['env']) + if isinstance(cs_out, bytes): + cs_out = cs_out.decode('utf-8', errors='replace') + output += cs_out except subprocess.CalledProcessError as e: ret = e.returncode - output += e.output + err_out2 = e.output + if isinstance(err_out2, bytes): + err_out2 = err_out2.decode('utf-8', errors='replace') + output += err_out2 for f in contents: f.update_time() @@ -395,9 +410,9 @@ def subconfigure(args): args, others = parser.parse_known_args(args) subconfigures = args.subconfigures if args.list: - subconfigures.extend(open(args.list, 'rb').read().splitlines()) + subconfigures.extend(open(args.list, 'r').read().splitlines()) if args.skip: - skips = set(open(args.skip, 'rb').read().splitlines()) + skips = set(open(args.skip, 'r').read().splitlines()) subconfigures = [s for s in subconfigures if s not in skips] if not subconfigures: @@ -410,7 +425,7 @@ def subconfigure(args): pool = Pool(len(subconfigures)) for relobjdir, returncode, output in \ pool.imap_unordered(run, subconfigures): - print prefix_lines(output, relobjdir) + print(prefix_lines(output, relobjdir)) sys.stdout.flush() ret = max(returncode, ret) if ret: diff --git a/build/submit_telemetry_data.py b/build/submit_telemetry_data.py index 918d840b7b..58c6d203fa 100644 --- a/build/submit_telemetry_data.py +++ b/build/submit_telemetry_data.py @@ -36,7 +36,7 @@ def submit_telemetry_data(statedir): path = os.path.join(outgoing, filename) if os.path.isdir(path) or not path.endswith('.json'): continue - with open(path, 'r') as f: + with open(path) as f: data = f.read() try: r = session.post(BUILD_TELEMETRY_SERVER, data=data, diff --git a/build/upload.py b/build/upload.py index c6bc10429b..7b9d4d7745 100644 --- a/build/upload.py +++ b/build/upload.py @@ -104,10 +104,10 @@ def DoSSHCommand(command, user, host, port=None, ssh_key=None): try: output = f(cmdline, stderr=STDOUT).strip() except CalledProcessError as e: - print "failed ssh command output:" - print '=' * 20 - print e.output - print '=' * 20 + print("failed ssh command output:") + print('=' * 20) + print(e.output) + print('=' * 20) raise return output @@ -118,7 +118,7 @@ def DoSCPFile(file, remote_path, user, host, port=None, ssh_key=None, """Upload file to user@host:remote_path using scp. Optionally use port and ssh_key, if provided.""" if log: - print 'Uploading %s' % file + print('Uploading %s' % file) cmdline = ["scp"] AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key) cmdline.extend([WindowsPathToMsysPath(file), @@ -221,7 +221,7 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, if not host or not user: return {} if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir): - print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \ + print("One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \) "defined." sys.exit(1) @@ -269,18 +269,18 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, if post_upload_command is not None: if verbose: - print "Running post-upload command: " + post_upload_command + print("Running post-upload command: " + post_upload_command) file_list = '"' + '" "'.join(remote_files) + '"' output = DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key) # We print since mozharness may parse URLs from the output stream. - print output + print(output) properties = GetUrlProperties(output, package) finally: if upload_to_temp_dir: DoSSHCommand("rm -rf %s" % path, user, host, port=port, ssh_key=ssh_key) if verbose: - print "Upload complete" + print("Upload complete") return properties def CopyFilesLocally(path, files, verbose=False, base_path=None, package=None): @@ -299,7 +299,7 @@ def CopyFilesLocally(path, files, verbose=False, base_path=None, package=None): if not os.path.exists(target_path): os.makedirs(target_path) if verbose: - print "Copying " + file + " to " + target_path + print("Copying " + file + " to " + target_path) shutil.copy(file, target_path) def WriteProperties(files, properties_file, url_properties, package): @@ -341,20 +341,20 @@ if __name__ == '__main__': help="Name of the main package.") (options, args) = parser.parse_args() if len(args) < 1: - print "You must specify at least one file to upload" + print("You must specify at least one file to upload") sys.exit(1) if not options.properties_file: - print "You must specify a --properties-file" + print("You must specify a --properties-file") sys.exit(1) if host == "localhost": if upload_to_temp_dir: - print "Cannot use UPLOAD_TO_TEMP with UPLOAD_HOST=localhost" + print("Cannot use UPLOAD_TO_TEMP with UPLOAD_HOST=localhost") sys.exit(1) if post_upload_command: # POST_UPLOAD_COMMAND is difficult to extract from the mozharness # scripts, so just ignore it until it's no longer used anywhere - print "Ignoring POST_UPLOAD_COMMAND with UPLOAD_HOST=localhost" + print("Ignoring POST_UPLOAD_COMMAND with UPLOAD_HOST=localhost") try: if host == "localhost": @@ -371,5 +371,5 @@ if __name__ == '__main__': WriteProperties(args, options.properties_file, url_properties, options.package) except IOError, (strerror): - print strerror + print(strerror) sys.exit(1) diff --git a/build/util/count_ctors.py b/build/util/count_ctors.py index 6a3a870685..58e45dc78a 100644 --- a/build/util/count_ctors.py +++ b/build/util/count_ctors.py @@ -1,4 +1,3 @@ - #!/usr/bin/python import json import re @@ -36,7 +35,7 @@ def count_ctors(filename): # Even if we have .ctors, we shouldn't have any constructors in .ctors. # Complain if .ctors does not look how we expect it to. if have_ctors and n_ctors_ctors != 0: - print >>sys.stderr, "Unexpected .ctors contents for", filename + print("Unexpected .ctors contents for", filename, file=sys.stderr) sys.exit(1) return n_init_array_ctors if have_ctors: @@ -44,7 +43,7 @@ def count_ctors(filename): # We didn't find anything; somebody switched initialization mechanisms on # us, or the binary is completely busted. Complain either way. - print >>sys.stderr, "Couldn't find .init_array or .ctors in", filename + print("Couldn't find .init_array or .ctors in", filename, file=sys.stderr) sys.exit(1) if __name__ == '__main__': @@ -60,5 +59,5 @@ if __name__ == '__main__': }]} ] } - print "PERFHERDER_DATA: %s" % json.dumps(perfherder_data) + print("PERFHERDER_DATA: %s" % json.dumps(perfherder_data)) diff --git a/build/util/hg.py b/build/util/hg.py index c76c8ef033..5656a28055 100644 --- a/build/util/hg.py +++ b/build/util/hg.py @@ -2,8 +2,8 @@ import os import re import subprocess -from urlparse import urlsplit -from ConfigParser import RawConfigParser +from urllib.parse import urlsplit +from configparser import RawConfigParser from util.commands import run_cmd, get_output, remove_path from util.retry import retry @@ -34,7 +34,7 @@ def make_hg_url(hgHost, repoPath, protocol='https', revision=None, filename=None): """construct a valid hg url from a base hg url (hg.mozilla.org), repoPath, revision and possible filename""" - base = '%s://%s' % (protocol, hgHost) + base = '{}://{}'.format(protocol, hgHost) repo = '/'.join(p.strip('/') for p in [base, repoPath]) if not filename: if not revision: @@ -88,7 +88,7 @@ def hg_ver(): """Returns the current version of hg, as a tuple of (major, minor, build)""" ver_string = get_output(['hg', '-q', 'version']) - match = re.search("\(version ([0-9.]+)\)", ver_string) + match = re.search(r"\(version ([0-9.]+)\)", ver_string) if match: bits = match.group(1).split(".") if len(bits) < 3: @@ -105,7 +105,7 @@ def purge(dest): try: run_cmd(['hg', '--config', 'extensions.purge=', 'purge', '-a', '--all', dest], cwd=dest) - except subprocess.CalledProcessError, e: + except subprocess.CalledProcessError as e: log.debug('purge failed: %s' % e) raise @@ -306,7 +306,7 @@ def out(src, remote, **kwargs): branch = "default" revs.append((rev, branch)) return revs - except subprocess.CalledProcessError, inst: + except subprocess.CalledProcessError as inst: # In some situations, some versions of Mercurial return "1" # if no changes are found, so we need to ignore this return code if inst.returncode == 1: @@ -500,7 +500,7 @@ def apply_and_push(localrepo, remote, changer, max_attempts=10, push(src=localrepo, remote=remote, ssh_username=ssh_username, ssh_key=ssh_key, force=force) return - except subprocess.CalledProcessError, e: + except subprocess.CalledProcessError as e: log.debug("Hit error when trying to push: %s" % str(e)) if n == max_attempts: log.debug("Tried %d times, giving up" % max_attempts) @@ -515,7 +515,7 @@ def apply_and_push(localrepo, remote, changer, max_attempts=10, try: run_cmd(['hg', '--config', 'ui.merge=internal:merge', 'rebase'], cwd=localrepo) - except subprocess.CalledProcessError, e: + except subprocess.CalledProcessError as e: log.debug("Failed to rebase: %s" % str(e)) update(localrepo, branch=branch) for r in reversed(new_revs): diff --git a/build/valgrind/mach_commands.py b/build/valgrind/mach_commands.py index 8109f0784a..d3e28e1daa 100644 --- a/build/valgrind/mach_commands.py +++ b/build/valgrind/mach_commands.py @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from __future__ import absolute_import, unicode_literals import logging import os diff --git a/build/valgrind/output_handler.py b/build/valgrind/output_handler.py index df24ff28be..30be3a180d 100644 --- a/build/valgrind/output_handler.py +++ b/build/valgrind/output_handler.py @@ -2,12 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from __future__ import print_function, unicode_literals import logging import re -class OutputHandler(object): +class OutputHandler: ''' A class for handling Valgrind output. diff --git a/build/variables.py b/build/variables.py index de0903af28..dc6205d7cc 100644 --- a/build/variables.py +++ b/build/variables.py @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from __future__ import print_function, unicode_literals import os import subprocess @@ -90,7 +89,7 @@ def source_repo_header(output): output.write('#define MOZ_SOURCE_STAMP %s\n' % changeset) if repo and buildconfig.substs.get('MOZ_INCLUDE_SOURCE_INFO'): - source = '%s/rev/%s' % (repo, changeset) + source = '{}/rev/{}'.format(repo, changeset) output.write('#define MOZ_SOURCE_REPO %s\n' % repo) output.write('#define MOZ_SOURCE_URL %s\n' % source) diff --git a/build/win32/autobinscope.py b/build/win32/autobinscope.py index fdba68e0c3..bdc5d27f69 100644 --- a/build/win32/autobinscope.py +++ b/build/win32/autobinscope.py @@ -23,7 +23,7 @@ BINSCOPE_OUTPUT_LOGFILE = r".\binscope_xml_output.log" # usage if len(sys.argv) < 3: - print """usage : autobinscope.by path_to_binary path_to_symbols [log_file_path]" + print("""usage : autobinscope.by path_to_binary path_to_symbols [log_file_path]") log_file_path is optional, log will be written to .\binscope_xml_output.log by default""" sys.exit(0) @@ -40,7 +40,7 @@ else: try: binscope_path = os.environ['BINSCOPE'] except KeyError: - print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status." + print("BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status.") sys.exit(0) try: @@ -53,11 +53,11 @@ try: except WindowsError, (errno, strerror): if errno != 2 and errno != 3: - print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n" + print("Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n") sys.exit(0) else: - print "Could not locate binscope at location : %s\n" % binscope_path - print "Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting..." + print("Could not locate binscope at location : %s\n" % binscope_path) + print("Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting...") sys.exit(0) proc.wait() @@ -66,10 +66,10 @@ output = proc.communicate()[0] # is this a PASS or a FAIL ? if proc.returncode != 0: - print "Error count: %d" % proc.returncode - print "TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path + print("Error count: %d" % proc.returncode) + print("TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path) logfile = open(log_file_path, "r") for line in logfile: print(line), else: - print "TEST-PASS | autobinscope.py | %s succeeded" % binary_path + print("TEST-PASS | autobinscope.py | %s succeeded" % binary_path) diff --git a/build/win32/pgomerge.py b/build/win32/pgomerge.py index 313d66870d..8d0351d960 100755 --- a/build/win32/pgomerge.py +++ b/build/win32/pgomerge.py @@ -39,6 +39,6 @@ def MergePGOFiles(basename, pgddir, pgcdir): if __name__ == '__main__': if len(sys.argv) != 3: - print >>sys.stderr, "Usage: pgomerge.py " + print("Usage: pgomerge.py ", file=sys.stderr) sys.exit(1) MergePGOFiles(sys.argv[1], os.getcwd(), sys.argv[2]) diff --git a/build/win32/procmem.py b/build/win32/procmem.py index 8376d07ea4..61621783f4 100644 --- a/build/win32/procmem.py +++ b/build/win32/procmem.py @@ -40,9 +40,9 @@ if __name__ == '__main__': 0, # no inherit int(pid)) if handle: - print "Process %s:" % pid + print("Process %s:" % pid) vsize, peak_vsize = get_vmsize(handle) - print "peak vsize: %d" % peak_vsize + print("peak vsize: %d" % peak_vsize) ctypes.windll.kernel32.CloseHandle(handle) else: - print "Couldn't open process %s" % pid + print("Couldn't open process %s" % pid) diff --git a/build/windows_toolchain.py b/build/windows_toolchain.py index 22e656eff3..5a8552c1e6 100644 --- a/build/windows_toolchain.py +++ b/build/windows_toolchain.py @@ -10,7 +10,6 @@ # When updating behavior of this script, remember to update the docs # in ``build/docs/toolchains.rst``. -from __future__ import absolute_import, unicode_literals import hashlib import os @@ -200,7 +199,7 @@ def format_manifest(manifest): def write_zip(zip_path, prefix=None): """Write toolchain data to a zip file.""" - if isinstance(prefix, unicode): + if isinstance(prefix, str): prefix = prefix.encode('utf-8') with JarWriter(file=zip_path, optimize=False, compress=5) as zip: diff --git a/client.py b/client.py index d832c4287d..fe10a0d61a 100755 --- a/client.py +++ b/client.py @@ -4,6 +4,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function LIBFFI_DIRS = (('js/ctypes/libffi', 'libffi'),) HG_EXCLUSIONS = ['.hg', '.hgignore', '.hgtags'] @@ -22,7 +23,7 @@ if topsrcdir == '': topsrcdir = '.' def check_call_noisy(cmd, *args, **kwargs): - print "Executing command:", cmd + print("Executing command:", cmd) check_call(cmd, *args, **kwargs) def do_hg_pull(dir, repository, hg): @@ -67,22 +68,22 @@ def do_cvs_export(modules, tag, cvsroot, cvs): cvs_module = module_tuple[1] fullpath = os.path.join(topsrcdir, module) if os.path.exists(fullpath): - print "Removing '%s'" % fullpath + print("Removing '%s'" % fullpath) shutil.rmtree(fullpath) (parent, leaf) = os.path.split(module) - print "CVS export begin: " + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC") + print("CVS export begin: " + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")) check_call_noisy([cvs, '-d', cvsroot, 'export', '-r', tag, '-d', leaf, cvs_module], cwd=os.path.join(topsrcdir, parent)) - print "CVS export end: " + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC") + print("CVS export end: " + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")) def toggle_trailing_blank_line(depname): """If the trailing line is empty, then we'll delete it. Otherwise we'll add a blank line.""" lines = open(depname, "r").readlines() if not lines: - print >>sys.stderr, "unexpected short file" + print("unexpected short file", file=sys.stderr) return if not lines[-1].strip(): @@ -95,7 +96,7 @@ def toggle_trailing_blank_line(depname): def get_trailing_blank_line_state(depname): lines = open(depname, "r").readlines() if not lines: - print >>sys.stderr, "unexpected short file" + print("unexpected short file", file=sys.stderr) return "no blank line" if not lines[-1].strip(): @@ -104,18 +105,18 @@ def get_trailing_blank_line_state(depname): return "no blank line" def update_nspr_or_nss(tag, depfile, destination, hgpath): - print "reverting to HG version of %s to get its blank line state" % depfile + print("reverting to HG version of %s to get its blank line state" % depfile) check_call_noisy([options.hg, 'revert', depfile]) old_state = get_trailing_blank_line_state(depfile) - print "old state of %s is: %s" % (depfile, old_state) + print("old state of %s is: %s" % (depfile, old_state)) do_hg_replace(destination, hgpath, tag, HG_EXCLUSIONS, options.hg) new_state = get_trailing_blank_line_state(depfile) - print "new state of %s is: %s" % (depfile, new_state) + print("new state of %s is: %s" % (depfile, new_state)) if old_state == new_state: - print "toggling blank line in: ", depfile + print("toggling blank line in: ", depfile) toggle_trailing_blank_line(depfile) tag_file = destination + "/TAG-INFO" - print >>file(tag_file, "w"), tag + print(tag, file=open(tag_file, "w")) o = OptionParser(usage="client.py [options] update_nspr tagname | update_nss tagname | update_libffi tagname") o.add_option("--skip-mozilla", dest="skip_mozilla", @@ -139,7 +140,7 @@ except IndexError: sys.exit(2) if action in ('checkout', 'co'): - print >>sys.stderr, "Warning: client.py checkout is obsolete." + print("Warning: client.py checkout is obsolete.", file=sys.stderr) pass elif action in ('update_nspr'): tag, = args[1:] diff --git a/config/MozZipFile.py b/config/MozZipFile.py index 337fe0521b..dc7add4c3a 100644 --- a/config/MozZipFile.py +++ b/config/MozZipFile.py @@ -18,7 +18,7 @@ class ZipFile(zipfile.ZipFile): def __init__(self, file, mode="r", compression=zipfile.ZIP_STORED, lock = False): if lock: - assert isinstance(file, basestring) + assert isinstance(file, str) self.lockfile = lock_file(file + '.lck') else: self.lockfile = None @@ -46,7 +46,7 @@ class ZipFile(zipfile.ZipFile): date_time=time.localtime(time.time())) zinfo.compress_type = self.compression # Add some standard UNIX file access permissions (-rw-r--r--). - zinfo.external_attr = (0x81a4 & 0xFFFF) << 16L + zinfo.external_attr = (0x81a4 & 0xFFFF) << 16 else: zinfo = zinfo_or_arcname @@ -58,7 +58,7 @@ class ZipFile(zipfile.ZipFile): # as the old, reuse the existing entry. doSeek = False # store if we need to seek to the eof after overwriting - if self.NameToInfo.has_key(zinfo.filename): + if zinfo.filename in self.NameToInfo: # Find the last ZipInfo with our name. # Last, because that's catching multiple overwrites i = len(self.filelist) @@ -109,14 +109,14 @@ class ZipFile(zipfile.ZipFile): # adjust file mode if we originally just wrote, now we rewrite self.fp.close() self.fp = open(self.filename, 'r+b') - all = map(lambda zi: (zi, True), self.filelist) + \ - map(lambda zi: (zi, False), self._remove) + all = [(zi, True) for zi in self.filelist] + \ + [(zi, False) for zi in self._remove] all.sort(lambda l, r: cmp(l[0].header_offset, r[0].header_offset)) # empty _remove for multiple closes self._remove = [] lengths = [all[i+1][0].header_offset - all[i][0].header_offset - for i in xrange(len(all)-1)] + for i in range(len(all)-1)] lengths.append(self.end - all[-1][0].header_offset) to_pos = 0 for (zi, keep), length in zip(all, lengths): diff --git a/config/check_source_count.py b/config/check_source_count.py index e347e7a55e..7f993f0390 100755 --- a/config/check_source_count.py +++ b/config/check_source_count.py @@ -24,7 +24,7 @@ details = {} count = 0 for f in files: - text = file(f).read() + text = open(f).read() match = re.findall(search_string, text) if match: num = len(match) diff --git a/config/createprecomplete.py b/config/createprecomplete.py index 3241d526b2..d70f282ace 100644 --- a/config/createprecomplete.py +++ b/config/createprecomplete.py @@ -56,10 +56,10 @@ def generate_precomplete(root_path): precomplete_file = open(precomplete_file_path, "wb") rel_file_path_list, rel_dir_path_list = get_build_entries(root_path) for rel_file_path in rel_file_path_list: - precomplete_file.writelines("remove \""+rel_file_path+"\"\n") + precomplete_file.write(("remove \""+rel_file_path+"\"\n").encode('utf-8')) for rel_dir_path in rel_dir_path_list: - precomplete_file.writelines("rmdir \""+rel_dir_path+"\"\n") + precomplete_file.write(("rmdir \""+rel_dir_path+"\"\n").encode('utf-8')) precomplete_file.close() diff --git a/config/expandlibs.py b/config/expandlibs.py index ac06c432f2..668db68bef 100644 --- a/config/expandlibs.py +++ b/config/expandlibs.py @@ -27,6 +27,7 @@ ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} following these rules: rules. ''' from __future__ import with_statement +from __future__ import print_function import sys, os, errno import expandlibs_config as conf @@ -36,7 +37,7 @@ def ensureParentDir(file): if dir and not os.path.exists(dir): try: os.makedirs(dir) - except OSError, error: + except OSError as error: if error.errno != errno.EEXIST: raise @@ -140,4 +141,4 @@ class ExpandArgs(list): return [relativize(arg)] if __name__ == '__main__': - print " ".join(ExpandArgs(sys.argv[1:])) + print(" ".join(ExpandArgs(sys.argv[1:]))) diff --git a/config/expandlibs_exec.py b/config/expandlibs_exec.py index fe9a7f6ebb..adc46a2911 100644 --- a/config/expandlibs_exec.py +++ b/config/expandlibs_exec.py @@ -21,6 +21,7 @@ relevant linker options to change the order in which the linker puts the symbols appear in the resulting binary. Only works for ELF targets. ''' from __future__ import with_statement +from __future__ import print_function import sys import os from expandlibs import ( @@ -305,11 +306,11 @@ class SectionFinder(object): return syms def print_command(out, args): - print >>out, "Executing: " + " ".join(args) + print("Executing: " + " ".join(args), file=out) for tmp in [f for f in args.tmp if os.path.isfile(f)]: - print >>out, tmp + ":" + print(tmp + ":", file=out) with open(tmp) as file: - print >>out, "".join([" " + l for l in file.readlines()]) + print("".join([" " + l for l in file.readlines()]), file=out) out.flush() def main(args, proc_callback=None): @@ -339,13 +340,13 @@ def main(args, proc_callback=None): proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) if proc_callback: proc_callback(proc) - except Exception, e: - print >>sys.stderr, 'error: Launching', args, ':', e + except Exception as e: + print('error: Launching', args, ':', e, file=sys.stderr) raise e (stdout, stderr) = proc.communicate() if proc.returncode and not options.verbose: print_command(sys.stderr, args) - sys.stderr.write(stdout) + sys.stderr.write(stdout.decode('utf-8', 'replace')) sys.stderr.flush() if proc.returncode: return proc.returncode diff --git a/config/expandlibs_gen.py b/config/expandlibs_gen.py index b1de63cd02..003e18f910 100644 --- a/config/expandlibs_gen.py +++ b/config/expandlibs_gen.py @@ -6,6 +6,7 @@ descriptor to standard output''' from __future__ import with_statement +from __future__ import print_function import sys import os import expandlibs_config as conf @@ -38,4 +39,4 @@ if __name__ == '__main__': ensureParentDir(options.output) with open(options.output, 'w') as outfile: - print >>outfile, generate(args) + print(generate(args), file=outfile) diff --git a/config/find_OOM_errors.py b/config/find_OOM_errors.py index 16065119b7..830693885e 100644 --- a/config/find_OOM_errors.py +++ b/config/find_OOM_errors.py @@ -105,7 +105,7 @@ def count_lines(): lines.sort() - countlog = file("../OOM_count_log", "w") + countlog = open("../OOM_count_log", "w") countlog.write("\n".join(lines)) countlog.flush() countlog.close() @@ -215,7 +215,7 @@ else: if OPTIONS.regression == None: # Don't use a logfile, this is automated for tinderbox. - log = file("../OOM_log", "w") + log = open("../OOM_log", "w") num_failures = 0 @@ -267,7 +267,7 @@ for f in files: # Get valgrind output for a good stack trace vcommand = "valgrind --dsymutil=yes -q --log-file=OOM_valgrind_log_file " + command run(vcommand) - vout = file("OOM_valgrind_log_file").read() + vout = open("OOM_valgrind_log_file").read() vout = clean_voutput(vout) sans_alloc_sites = remove_failed_allocation_backtraces(vout) diff --git a/config/link.py b/config/link.py index be63216a02..aa47503f0d 100644 --- a/config/link.py +++ b/config/link.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import expandlibs_exec import sys import threading @@ -18,7 +19,7 @@ def periodically_print_status(proc): time.sleep(0.5) idleTime += 0.5 if idleTime > 20 * 60: - print "Still linking, 20 minutes passed..." + print("Still linking, 20 minutes passed...") sys.stdout.flush() idleTime = 0 @@ -42,6 +43,6 @@ def wrap_linker(args): if __name__ == "__main__": if len(sys.argv) < 2: - print >>sys.stderr, "Usage: link.py " + print("Usage: link.py ", file=sys.stderr) sys.exit(1) sys.exit(wrap_linker(sys.argv[1:])) diff --git a/config/mozunit.py b/config/mozunit.py index 3dddf84ee4..69a3220050 100644 --- a/config/mozunit.py +++ b/config/mozunit.py @@ -140,7 +140,7 @@ class MockedOpen(object): ''' def __init__(self, files = {}): self.files = {} - for name, content in files.iteritems(): + for name, content in files.items(): self.files[normcase(os.path.abspath(name))] = content def __call__(self, name, mode = 'r'): @@ -158,19 +158,19 @@ class MockedOpen(object): return file def __enter__(self): - import __builtin__ - self.open = __builtin__.open + import builtins + self.open = builtins.open self._orig_path_exists = os.path.exists self._orig_path_isdir = os.path.isdir self._orig_path_isfile = os.path.isfile - __builtin__.open = self + builtins.open = self os.path.exists = self._wrapped_exists os.path.isdir = self._wrapped_isdir os.path.isfile = self._wrapped_isfile def __exit__(self, type, value, traceback): - import __builtin__ - __builtin__.open = self.open + import builtins + builtins.open = self.open os.path.exists = self._orig_path_exists os.path.isdir = self._orig_path_isdir os.path.isfile = self._orig_path_isfile diff --git a/config/nsinstall.py b/config/nsinstall.py index 4814133703..73dac0021d 100755 --- a/config/nsinstall.py +++ b/config/nsinstall.py @@ -149,7 +149,7 @@ def _nsinstall_internal(argv): # nsinstall as a native command is always UTF-8 def nsinstall(argv): - return _nsinstall_internal([unicode(arg, "utf-8") for arg in argv]) + return _nsinstall_internal([str(arg, "utf-8") for arg in argv]) if __name__ == '__main__': # sys.argv corrupts characters outside the system code page on Windows @@ -174,9 +174,6 @@ if __name__ == '__main__': argv = argv_arr[1:argc.value] else: # For consistency, do it on Unix as well - if sys.stdin.encoding is not None: - argv = [unicode(arg, sys.stdin.encoding) for arg in sys.argv] - else: - argv = [unicode(arg) for arg in sys.argv] + argv = [str(arg) for arg in sys.argv] sys.exit(_nsinstall_internal(argv[1:])) diff --git a/config/printconfigsetting.py b/config/printconfigsetting.py index ef900a6c05..e6c764019d 100644 --- a/config/printconfigsetting.py +++ b/config/printconfigsetting.py @@ -2,30 +2,31 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import configobj import sys import re -from StringIO import StringIO +from io import StringIO try: (file, section, key) = sys.argv[1:] except ValueError: - print "Usage: printconfigsetting.py
" + print("Usage: printconfigsetting.py
") sys.exit(1) with open(file) as fh: - content = re.sub('^\s*;', '#', fh.read(), flags=re.M) + content = re.sub(r'^\s*;', '#', fh.read(), flags=re.M) c = configobj.ConfigObj(StringIO(content)) try: s = c[section] except KeyError: - print >>sys.stderr, "Section [%s] not found." % section + print("Section [%s] not found." % section, file=sys.stderr) sys.exit(1) try: - print s[key] + print(s[key]) except KeyError: - print >>sys.stderr, "Key %s not found." % key + print("Key %s not found." % key, file=sys.stderr) sys.exit(1) diff --git a/config/pythonpath.py b/config/pythonpath.py index 0318066148..12fe6b1c73 100644 --- a/config/pythonpath.py +++ b/config/pythonpath.py @@ -7,9 +7,10 @@ Run a python script, adding extra directories to the python path. """ +from __future__ import print_function def main(args): def usage(): - print >>sys.stderr, "pythonpath.py -I directory script.py [args...]" + print("pythonpath.py -I directory script.py [args...]", file=sys.stderr) sys.exit(150) paths = [] @@ -45,7 +46,7 @@ def main(args): frozenglobals['__name__'] = '__main__' frozenglobals['__file__'] = script - execfile(script, frozenglobals) + exec(compile(open(script, "rb").read(), script, 'exec'), frozenglobals) # Freeze scope here ... why this makes things work I have no idea ... frozenglobals = globals() diff --git a/config/rebuild_check.py b/config/rebuild_check.py index a6c3dc87ac..d7540c9359 100644 --- a/config/rebuild_check.py +++ b/config/rebuild_check.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import os import errno @@ -18,7 +19,7 @@ def rebuild_check(args): deps = args[1:] t = mtime(target) if t < 0: - print target + print(target) return newer = [] @@ -31,13 +32,13 @@ def rebuild_check(args): newer.append(dep) if newer and removed: - print 'Rebuilding %s because %s changed and %s was removed' % (target, ', '.join(newer), ', '.join(removed)) + print('Rebuilding %s because %s changed and %s was removed' % (target, ', '.join(newer), ', '.join(removed))) elif newer: - print 'Rebuilding %s because %s changed' % (target, ', '.join(newer)) + print('Rebuilding %s because %s changed' % (target, ', '.join(newer))) elif removed: - print 'Rebuilding %s because %s was removed' % (target, ', '.join(removed)) + print('Rebuilding %s because %s was removed' % (target, ', '.join(removed))) else: - print 'Rebuilding %s for an unknown reason' % target + print('Rebuilding %s for an unknown reason' % target) if __name__ == '__main__': import sys diff --git a/config/tests/unit-expandlibs.py b/config/tests/unit-expandlibs.py index 3c7e5a44dd..e1b8775961 100644 --- a/config/tests/unit-expandlibs.py +++ b/config/tests/unit-expandlibs.py @@ -8,6 +8,7 @@ from shutil import rmtree import mozunit from UserString import UserString +import six # Create a controlled configuration for use by expandlibs config_win = { 'AR': 'lib', @@ -120,8 +121,7 @@ class ReplicateTests(type): del dict[name] return type.__new__(cls, clsName, bases, dict) -class TestCaseWithTmpDir(unittest.TestCase): - __metaclass__ = ReplicateTests +class TestCaseWithTmpDir(six.with_metaclass(ReplicateTests, unittest.TestCase)): def init(self): self.tmpdir = os.path.abspath(mkdtemp(dir=os.curdir)) diff --git a/config/tests/unit-nsinstall.py b/config/tests/unit-nsinstall.py index 2a230841a1..ea95fd2180 100644 --- a/config/tests/unit-nsinstall.py +++ b/config/tests/unit-nsinstall.py @@ -28,9 +28,9 @@ class TestNsinstall(unittest.TestCase): # Unicode strings means non-ASCII children can be deleted properly on # Windows if sys.stdin.encoding is None: - tmpdir = unicode(self.tmpdir) + tmpdir = str(self.tmpdir) else: - tmpdir = unicode(self.tmpdir, sys.stdin.encoding) + tmpdir = str(self.tmpdir, sys.stdin.encoding) rmtree(tmpdir) # utility methods for tests diff --git a/config/tests/unitMozZipFile.py b/config/tests/unitMozZipFile.py index f9c0419ab5..255e61dd2b 100644 --- a/config/tests/unitMozZipFile.py +++ b/config/tests/unitMozZipFile.py @@ -11,6 +11,7 @@ import sys import random import copy from string import letters +from functools import reduce ''' Test case infrastructure for MozZipFile. @@ -38,7 +39,7 @@ leafs = ( 'firstdir/oneleaf', 'seconddir/twoleaf', 'thirddir/with/sub/threeleaf') -_lengths = map(lambda n: n * 64, [16, 64, 80]) +_lengths = [n * 64 for n in [16, 64, 80]] lengths = 3 writes = 5 @@ -71,7 +72,7 @@ def getid(descs): def getContent(length): 'Get pseudo random content of given length.' rv = [None] * length - for i in xrange(length): + for i in range(length): rv[i] = random.choice(letters) return ''.join(rv) @@ -136,10 +137,10 @@ class TestExtensiveStored(unittest.TestCase): self.failIf(badEntry, badEntry) zlist = zf.namelist() zlist.sort() - vlist = self.ref.keys() + vlist = list(self.ref.keys()) vlist.sort() self.assertEqual(zlist, vlist) - for leaf, content in self.ref.iteritems(): + for leaf, content in self.ref.items(): zcontent = zf.read(leaf) self.assertEqual(content, zcontent) @@ -158,16 +159,16 @@ class TestExtensiveStored(unittest.TestCase): open(self.leaf('stage', leaf), 'w').write(content) # all leafs in all lengths -atomics = list(prod(xrange(len(leafs)), xrange(lengths))) +atomics = list(prod(range(len(leafs)), range(lengths))) # populate TestExtensiveStore with testcases -for w in xrange(writes): +for w in range(writes): # Don't iterate over all files for the the first n passes, # those are redundant as long as w < lengths. # There are symmetries in the trailing end, too, but I don't know # how to reduce those out right now. - nonatomics = [list(prod(range(min(i,len(leafs))), xrange(lengths))) - for i in xrange(1, w+1)] + [atomics] + nonatomics = [list(prod(list(range(min(i,len(leafs)))), range(lengths))) + for i in range(1, w+1)] + [atomics] for descs in prod(*nonatomics): suffix = getid(descs) dicts = [dict(leaf=leaf, length=length) for leaf, length in descs] @@ -181,9 +182,9 @@ for w in xrange(writes): # and then write all atomics again. # This should catch more or less all artifacts generated # by the final ordering step when closing the jar. -files = [list(prod([i], xrange(lengths))) for i in xrange(len(leafs))] +files = [list(prod([i], range(lengths))) for i in range(len(leafs))] allfiles = reduce(lambda l,r:l+r, - [list(prod(*files[:(i+1)])) for i in xrange(len(leafs))]) + [list(prod(*files[:(i+1)])) for i in range(len(leafs))]) for first in allfiles: testbasename = 'test{0}_'.format(getid(first)) diff --git a/configure.py b/configure.py index f7392d0ffa..abf9dca9dc 100644 --- a/configure.py +++ b/configure.py @@ -45,11 +45,11 @@ def config_status(config): sanitized_config = {} sanitized_config['substs'] = { - k: sanitized_bools(v) for k, v in config.iteritems() + k: sanitized_bools(v) for k, v in config.items() if k not in ('DEFINES', 'non_global_defines', 'TOPSRCDIR', 'TOPOBJDIR') } sanitized_config['defines'] = { - k: sanitized_bools(v) for k, v in config['DEFINES'].iteritems() + k: sanitized_bools(v) for k, v in config['DEFINES'].items() } sanitized_config['non_global_defines'] = config['non_global_defines'] sanitized_config['topsrcdir'] = config['TOPSRCDIR'] @@ -71,7 +71,7 @@ def config_status(config): ''') % {'python': config['PYTHON'], 'encoding': encoding}) # A lot of the build backend code is currently expecting byte # strings and breaks in subtle ways with unicode strings. (bug 1296508) - for k, v in sanitized_config.iteritems(): + for k, v in sanitized_config.items(): fh.write('%s = encode(%s, encoding)\n' % (k, indented_repr(v))) fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', " "'non_global_defines', 'substs', 'mozconfig']") @@ -88,7 +88,7 @@ def config_status(config): # executable permissions. os.chmod('config.status', 0o755) if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'): - os.environ[b'WRITE_MOZINFO'] = b'1' + os.environ['WRITE_MOZINFO'] = '1' from mozbuild.config_status import config_status # Some values in sanitized_config also have more complex types, such as @@ -99,7 +99,7 @@ def config_status(config): # A lot of the build backend code is currently expecting byte strings # and breaks in subtle ways with unicode strings. - return config_status(args=[], **encode(sanitized_config, encoding)) + return config_status(args=[], **sanitized_config) return 0 diff --git a/devtools/shared/css/generated/mach_commands.py b/devtools/shared/css/generated/mach_commands.py index 56f321a6f2..71728327ba 100644 --- a/devtools/shared/css/generated/mach_commands.py +++ b/devtools/shared/css/generated/mach_commands.py @@ -8,6 +8,7 @@ that uses inIDOMUtils to query the CSS properties used by the browser. This info is used to generate the properties-db.js file. """ +from __future__ import print_function import json import os import sys @@ -97,4 +98,4 @@ class MachCommands(MachCommandBase): with open(destination_path, 'wb') as destination: destination.write(preamble + contents) - print('The database was successfully generated at ' + destination_path) + print(('The database was successfully generated at ' + destination_path)) diff --git a/dom/base/test/websocket_hybi/file_binary-frames_wsh.py b/dom/base/test/websocket_hybi/file_binary-frames_wsh.py index 656d0e1890..2f9f379726 100644 --- a/dom/base/test/websocket_hybi/file_binary-frames_wsh.py +++ b/dom/base/test/websocket_hybi/file_binary-frames_wsh.py @@ -15,4 +15,4 @@ def web_socket_transfer_data(request): def all_distinct_bytes(): - return ''.join([chr(i) for i in xrange(256)]) + return ''.join([chr(i) for i in range(256)]) diff --git a/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py b/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py index 024e3f4d07..c63ca45f3a 100644 --- a/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py +++ b/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py @@ -18,4 +18,4 @@ def web_socket_transfer_data(request): def all_distinct_bytes(): - return ''.join([chr(i) for i in xrange(256)]) + return ''.join([chr(i) for i in range(256)]) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 17e5502504..99fe625672 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -13,6 +13,7 @@ import functools from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLInterfaceMember, IDLUndefinedValue, IDLEmptySequenceValue, IDLDictionary from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, getAllTypes, Descriptor, MemberIsUnforgeable, iteratorNativeType +from functools import reduce AUTOGENERATED_WARNING_COMMENT = \ "/* THIS FILE IS AUTOGENERATED BY Codegen.py - DO NOT EDIT */\n\n" @@ -1117,13 +1118,12 @@ class CGHeaders(CGWrapper): declareIncludes = set(declareIncludes) - def addHeadersForType((t, dictionary)): + def addHeadersForType(xxx_todo_changeme): """ Add the relevant headers for this type. We use dictionary, if passed, to decide what to do with interface types. """ - # Dictionaries have members that need to be actually - # declared, not just forward-declared. + (t, dictionary) = xxx_todo_changeme if dictionary: headerSet = declareIncludes else: @@ -1197,9 +1197,9 @@ class CGHeaders(CGWrapper): # parametrized over, if needed. addHeadersForType((t.inner, dictionary)) - map(addHeadersForType, + list(map(addHeadersForType, getAllTypes(descriptors + callbackDescriptors, dictionaries, - callbacks)) + callbacks))) # Now make sure we're not trying to include the header from inside itself declareIncludes.discard(prefix + ".h") @@ -2068,8 +2068,7 @@ class MemberCondition: if nonExposedGlobals: # Nonempty set self.nonExposedGlobals = " | ".join( - map(lambda g: "GlobalNames::%s" % g, - sorted(nonExposedGlobals))) + ["GlobalNames::%s" % g for g in sorted(nonExposedGlobals)]) else: self.nonExposedGlobals = "0" @@ -4677,7 +4676,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, declArgs=declArgs) def incrementNestingLevel(): - if nestingLevel is "": + if nestingLevel == "": return 1 return nestingLevel + 1 @@ -4999,7 +4998,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, memberTypes = type.flatMemberTypes names = [] - interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes) + interfaceMemberTypes = [t for t in memberTypes if t.isNonCallbackInterface()] if len(interfaceMemberTypes) > 0: interfaceObject = [] for memberType in interfaceMemberTypes: @@ -5013,7 +5012,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: interfaceObject = None - sequenceObjectMemberTypes = filter(lambda t: t.isSequence(), memberTypes) + sequenceObjectMemberTypes = [t for t in memberTypes if t.isSequence()] if len(sequenceObjectMemberTypes) > 0: assert len(sequenceObjectMemberTypes) == 1 name = getUnionMemberName(sequenceObjectMemberTypes[0]) @@ -5024,7 +5023,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: sequenceObject = None - dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes) + dateObjectMemberTypes = [t for t in memberTypes if t.isDate()] if len(dateObjectMemberTypes) > 0: assert len(dateObjectMemberTypes) == 1 memberType = dateObjectMemberTypes[0] @@ -5036,7 +5035,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: dateObject = None - callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes) + callbackMemberTypes = [t for t in memberTypes if t.isCallback() or t.isCallbackInterface()] if len(callbackMemberTypes) > 0: assert len(callbackMemberTypes) == 1 memberType = callbackMemberTypes[0] @@ -5048,7 +5047,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: callbackObject = None - dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes) + dictionaryMemberTypes = [t for t in memberTypes if t.isDictionary()] if len(dictionaryMemberTypes) > 0: assert len(dictionaryMemberTypes) == 1 name = getUnionMemberName(dictionaryMemberTypes[0]) @@ -5059,7 +5058,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: setDictionary = None - recordMemberTypes = filter(lambda t: t.isRecord(), memberTypes) + recordMemberTypes = [t for t in memberTypes if t.isRecord()] if len(recordMemberTypes) > 0: assert len(recordMemberTypes) == 1 name = getUnionMemberName(recordMemberTypes[0]) @@ -5070,7 +5069,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: recordObject = None - objectMemberTypes = filter(lambda t: t.isObject(), memberTypes) + objectMemberTypes = [t for t in memberTypes if t.isObject()] if len(objectMemberTypes) > 0: assert len(objectMemberTypes) == 1 # Very important to NOT construct a temporary Rooted here, since the @@ -5135,9 +5134,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, return CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" "break;\n" % (unionArgumentObj, name)) other = CGList([]) - stringConversion = map(getStringOrPrimitiveConversion, stringTypes) - numericConversion = map(getStringOrPrimitiveConversion, numericTypes) - booleanConversion = map(getStringOrPrimitiveConversion, booleanTypes) + stringConversion = list(map(getStringOrPrimitiveConversion, stringTypes)) + numericConversion = list(map(getStringOrPrimitiveConversion, numericTypes)) + booleanConversion = list(map(getStringOrPrimitiveConversion, booleanTypes)) if stringConversion: if booleanConversion: other.append(CGIfWrapper(booleanConversion[0], @@ -7744,7 +7743,7 @@ class CGPerSignatureCall(CGThing): } try: wrapCode += wrapForType(self.returnType, self.descriptor, resultTemplateValues) - except MethodNotNewObjectError, err: + except MethodNotNewObjectError as err: assert not returnsNewObject raise TypeError("%s being returned from non-NewObject method or property %s.%s" % (err.typename, @@ -8255,7 +8254,7 @@ class CGMethodCall(CGThing): # a string overload, then boolean and numeric are conditional, and # if not then boolean is conditional if we have a numeric overload. def findUniqueSignature(filterLambda): - sigs = filter(filterLambda, possibleSignatures) + sigs = list(filter(filterLambda, possibleSignatures)) assert len(sigs) < 2 if len(sigs) > 0: return sigs[0] @@ -9737,7 +9736,7 @@ class CGEnum(CGThing): return self.enum.identifier.name + "Values" def nEnumStrings(self): - return len(self.enum.values()) + 1 + return len(list(self.enum.values())) + 1 def declare(self): decl = fill( @@ -9748,7 +9747,7 @@ class CGEnum(CGThing): }; """, name=self.enum.identifier.name, - enums=",\n".join(map(getEnumValueName, self.enum.values())) + ",\n") + enums=",\n".join(map(getEnumValueName, list(self.enum.values()))) + ",\n") strings = CGNamespace(self.stringsNamespace(), CGGeneric(declare="extern const EnumEntry %s[%d];\n" % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings()))) @@ -13659,7 +13658,7 @@ class ForwardDeclarationBuilder: if self.decls: decls.append(CGList([CGClassForwardDeclare(cname, isStruct) for cname, isStruct in sorted(self.decls)])) - for namespace, child in sorted(self.children.iteritems()): + for namespace, child in sorted(self.children.items()): decls.append(CGNamespace(namespace, child._build(atTopLevel=False), declareOnly=True)) cg = CGList(decls, "\n") @@ -14009,10 +14008,10 @@ class CGBindingRoot(CGThing): # Add header includes. bindingHeaders = [header - for header, include in bindingHeaders.iteritems() + for header, include in bindingHeaders.items() if include] bindingDeclareHeaders = [header - for header, include in bindingDeclareHeaders.iteritems() + for header, include in bindingDeclareHeaders.items() if include] curr = CGHeaders(descriptors, @@ -14620,7 +14619,7 @@ class CGBindingImplClass(CGClass): (returnType, args), descriptor.getExtendedAttributes(op))) # Sort things by name so we get stable ordering in the output. - ops = descriptor.operations.items() + ops = list(descriptor.operations.items()) ops.sort(key=lambda x: x[0]) for name, op in ops: appendSpecialOperation(name, op) @@ -16970,7 +16969,7 @@ class GlobalGenRoots(): @staticmethod def UnionConversions(config): unionTypes = [] - for l in config.unionsPerFilename.itervalues(): + for l in config.unionsPerFilename.values(): unionTypes.extend(l) unionTypes.sort(key=lambda u: u.name) headers, unions = UnionConversions(unionTypes, @@ -17087,7 +17086,7 @@ class CGEventMethod(CGNativeMember): # -3 on the left to ignore the type, bubbles, and cancelable parameters # -1 on the right to ignore the .trusted property which bleeds through # here because it is [Unforgeable]. - len(signature[1]) - 3 == len(filter(lambda x: x.isAttr(), iface.members)) - 1): + len(signature[1]) - 3 == len([x for x in iface.members if x.isAttr()]) - 1): allowed = True self.isInit = True diff --git a/dom/bindings/Configuration.py b/dom/bindings/Configuration.py index 2669e3e4cd..20a93dffc6 100644 --- a/dom/bindings/Configuration.py +++ b/dom/bindings/Configuration.py @@ -28,7 +28,7 @@ class Configuration(DescriptorProvider): # Read the configuration file. glbl = {} - execfile(filename, glbl) + exec(compile(open(filename, "rb").read(), filename, 'exec'), glbl) config = glbl['DOMInterfaces'] # Build descriptors for all the interfaces we have in the parse data. @@ -87,7 +87,7 @@ class Configuration(DescriptorProvider): self.descriptorsByName[desc.interface.identifier.name] = desc # Keep the descriptor list sorted for determinism. - self.descriptors.sort(lambda x, y: cmp(x.name, y.name)) + self.descriptors.sort(key=lambda x: x.name) self.descriptorsByFile = {} @@ -149,8 +149,7 @@ class Configuration(DescriptorProvider): # unions for the file where we previously found # them. unionsForFilename = self.unionsPerFilename[f] - unionsForFilename = filter(lambda u: u.name != t.name, - unionsForFilename) + unionsForFilename = [u for u in unionsForFilename if u.name != t.name] if len(unionsForFilename) == 0: del self.unionsPerFilename[f] else: @@ -170,7 +169,7 @@ class Configuration(DescriptorProvider): # Collect up our filters, because we may have a webIDLFile filter that # we always want to apply first. tofilter = [] - for key, val in filters.iteritems(): + for key, val in filters.items(): if key == 'webIDLFile': # Special-case this part to make it fast, since most of our # getDescriptors calls are conditioned on a webIDLFile. We may @@ -210,17 +209,17 @@ class Configuration(DescriptorProvider): getter = (lambda attrName: lambda x: getattr(x, attrName))(key) tofilter.append((getter, val)) for f in tofilter: - curr = filter(lambda x: f[0](x) == f[1], curr) + curr = [x for x in curr if f[0](x) == f[1]] return curr def getEnums(self, webIDLFile): - return filter(lambda e: e.filename() == webIDLFile, self.enums) + return [e for e in self.enums if e.filename() == webIDLFile] def getDictionaries(self, webIDLFile): - return filter(lambda d: d.filename() == webIDLFile, self.dictionaries) + return [d for d in self.dictionaries if d.filename() == webIDLFile] def getCallbacks(self, webIDLFile): - return filter(lambda c: c.filename() == webIDLFile, self.callbacks) + return [c for c in self.callbacks if c.filename() == webIDLFile] def getDescriptor(self, interfaceName): """ @@ -491,7 +490,7 @@ class Descriptor(DescriptorProvider): if config == '*': iface = self.interface while iface: - add('all', map(lambda m: m.name, iface.members), attribute) + add('all', [m.name for m in iface.members], attribute) iface = iface.parent else: add('all', [config], attribute) @@ -543,7 +542,7 @@ class Descriptor(DescriptorProvider): @property def prototypeNameChain(self): - return map(lambda p: self.getDescriptor(p).name, self.prototypeChain) + return [self.getDescriptor(p).name for p in self.prototypeChain] @property def parentPrototypeName(self): diff --git a/dom/bindings/GenerateCSS2PropertiesWebIDL.py b/dom/bindings/GenerateCSS2PropertiesWebIDL.py index b1f2a6016d..5341d05780 100644 --- a/dom/bindings/GenerateCSS2PropertiesWebIDL.py +++ b/dom/bindings/GenerateCSS2PropertiesWebIDL.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import sys import string import argparse diff --git a/dom/bindings/mozwebidlcodegen/__init__.py b/dom/bindings/mozwebidlcodegen/__init__.py index 93b33012a7..928f194566 100644 --- a/dom/bindings/mozwebidlcodegen/__init__.py +++ b/dom/bindings/mozwebidlcodegen/__init__.py @@ -7,6 +7,7 @@ from __future__ import unicode_literals +from __future__ import print_function import errno import hashlib import json @@ -270,7 +271,7 @@ class WebIDLCodegenManager(LoggingMixin): # Generate bindings from .webidl files. for filename in sorted(changed_inputs): basename = mozpath.basename(filename) - print basename + print(basename) sys.stdout.flush() result.inputs.add(filename) written, deps = self._generate_build_files_for_webidl(filename) @@ -296,7 +297,7 @@ class WebIDLCodegenManager(LoggingMixin): if self._make_deps_path: mk = Makefile() codegen_rule = mk.create_rule([self._make_deps_target]) - codegen_rule.add_dependencies(global_hashes.keys()) + codegen_rule.add_dependencies(list(global_hashes.keys())) codegen_rule.add_dependencies(self._input_paths) with FileAvoidWrite(self._make_deps_path) as fh: @@ -314,7 +315,7 @@ class WebIDLCodegenManager(LoggingMixin): example_paths = self._example_paths(interface) for path in example_paths: - print "Generating %s" % path + print("Generating %s" % path) return self._maybe_write_codegen(root, *example_paths) @@ -331,9 +332,9 @@ class WebIDLCodegenManager(LoggingMixin): for path in sorted(self._input_paths): with open(path, 'rb') as fh: - data = fh.read() - hashes[path] = hashlib.sha1(data).hexdigest() - parser.parse(data, path) + raw = fh.read() + hashes[path] = hashlib.sha1(raw).hexdigest() + parser.parse(raw.decode('utf-8'), path) self._parser_results = parser.finish() self._config = Configuration(self._config_path, self._parser_results, @@ -519,7 +520,7 @@ class WebIDLCodegenManager(LoggingMixin): return False, current_hashes def _save_state(self): - with open(self._state_path, 'wb') as fh: + with open(self._state_path, 'w') as fh: self._state.dump(fh) def _maybe_write_codegen(self, obj, declare_path, define_path, result=None): diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 5c6b6eed32..7429ff073b 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -4,6 +4,7 @@ """ A WebIDL parser. """ +from __future__ import print_function from ply import lex, yacc import re import os @@ -60,9 +61,7 @@ def enum(*names, **kw): base = object start = 0 - class Foo(base): - __metaclass__ = M_add_class_attribs(names, start) - + class Foo(base, metaclass=M_add_class_attribs(names, start)): def __setattr__(self, name, value): # this makes it read-only raise NotImplementedError return Foo() @@ -93,6 +92,9 @@ class Location(object): return (self._lexpos == other._lexpos and self._file == other._file) + def __hash__(self): + return object.__hash__(self) + def filename(self): return self._file @@ -132,6 +134,9 @@ class BuiltinLocation(object): return (isinstance(other, BuiltinLocation) and self.msg == other.msg) + def __hash__(self): + return object.__hash__(self) + def filename(self): return '' @@ -962,7 +967,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins): # self.members. Sort our consequential interfaces by name # just so we have a consistent order. for iface in sorted(self.getConsequentialInterfaces(), - cmp=cmp, key=lambda x: x.identifier.name): # Flag the interface as being someone's consequential interface iface.setIsConsequentialInterfaceOf(self) @@ -1515,7 +1519,7 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins): assert len(naviProp) == 1 assert isinstance(naviProp, list) assert len(naviProp[0]) != 0 - conditionExtendedAttributes = self._extendedAttrDict.viewkeys() & IDLInterfaceOrNamespace.conditionExtendedAttributes + conditionExtendedAttributes = self._extendedAttrDict.keys() & IDLInterfaceOrNamespace.conditionExtendedAttributes attr = IDLAttribute(self.location, IDLUnresolvedIdentifier(BuiltinLocation(""), naviProp[0]), IDLUnresolvedType(self.location, IDLUnresolvedIdentifier(self.location, self.identifier.name)), @@ -1841,7 +1845,7 @@ class IDLDictionary(IDLObjectWithScope): assert member.type.isComplete() # Members of a dictionary are sorted in lexicographic order - self.members.sort(cmp=cmp, key=lambda x: x.identifier.name) + self.members.sort(key=lambda x: x.identifier.name) inheritedMembers = [] ancestor = self.parent @@ -2012,6 +2016,9 @@ class IDLType(IDLObject): def __eq__(self, other): return other and self.builtin == other.builtin and self.name == other.name + def __hash__(self): + return object.__hash__(self) + def __ne__(self, other): return not self == other @@ -2174,7 +2181,7 @@ class IDLUnresolvedType(IDLType): assert obj if obj.isType(): - print obj + print(obj) assert not obj.isType() if obj.isTypedef(): assert self.name.name == obj.identifier.name @@ -2230,6 +2237,9 @@ class IDLNullableType(IDLParameterizedType): def __eq__(self, other): return isinstance(other, IDLNullableType) and self.inner == other.inner + def __hash__(self): + return object.__hash__(self) + def __str__(self): return self.inner.__str__() + "OrNull" @@ -2360,6 +2370,9 @@ class IDLSequenceType(IDLParameterizedType): def __eq__(self, other): return isinstance(other, IDLSequenceType) and self.inner == other.inner + def __hash__(self): + return object.__hash__(self) + def __str__(self): return self.inner.__str__() + "Sequence" @@ -2436,6 +2449,9 @@ class IDLRecordType(IDLParameterizedType): def __eq__(self, other): return isinstance(other, IDLRecordType) and self.inner == other.inner + def __hash__(self): + return object.__hash__(self) + def __str__(self): return self.keyType.__str__() + self.inner.__str__() + "Record" @@ -2604,6 +2620,9 @@ class IDLTypedefType(IDLType): def __eq__(self, other): return isinstance(other, IDLTypedefType) and self.inner == other.inner + def __hash__(self): + return object.__hash__(self) + def __str__(self): return self.name @@ -2729,6 +2748,9 @@ class IDLWrapperType(IDLType): self._identifier == other._identifier and self.builtin == other.builtin) + def __hash__(self): + return object.__hash__(self) + def __str__(self): return str(self.name) + " (Wrapper)" @@ -2884,6 +2906,9 @@ class IDLPromiseType(IDLParameterizedType): return (isinstance(other, IDLPromiseType) and self.promiseInnerType() == other.promiseInnerType()) + def __hash__(self): + return object.__hash__(self) + def __str__(self): return self.inner.__str__() + "Promise" @@ -3328,7 +3353,7 @@ class IDLValue(IDLObject): elif self.type.isString() and type.isEnum(): # Just keep our string, but make sure it's a valid value for this enum enum = type.unroll().inner - if self.value not in enum.values(): + if self.value not in list(enum.values()): raise WebIDLError("'%s' is not a valid default value for enum %s" % (self.value, enum.identifier.name), [location, enum.location]) @@ -3504,7 +3529,7 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins): def finish(self, scope): # We better be exposed _somewhere_. if (len(self._exposureGlobalNames) == 0): - print self.identifier.name + print(self.identifier.name) assert len(self._exposureGlobalNames) != 0 IDLExposureMixins.finish(self, scope) @@ -5261,7 +5286,7 @@ class Tokenizer(object): "ReadableStream": "READABLESTREAM", } - tokens.extend(keywords.values()) + tokens.extend(list(keywords.values())) def t_error(self, t): raise WebIDLError("Unrecognized Input", @@ -5417,7 +5442,7 @@ class Parser(Tokenizer): [location, existingObj.location]) existingObj.setNonPartial(*nonPartialArgs) return existingObj - except Exception, ex: + except Exception as ex: if isinstance(ex, WebIDLError): raise ex pass @@ -5455,7 +5480,7 @@ class Parser(Tokenizer): "%s and %s" % (identifier.name, p[0]), [location, p[0].location]) return - except Exception, ex: + except Exception as ex: if isinstance(ex, WebIDLError): raise ex pass @@ -5518,7 +5543,7 @@ class Parser(Tokenizer): "non-%s object" % (prettyname, prettyname), [location, nonPartialObject.location]) - except Exception, ex: + except Exception as ex: if isinstance(ex, WebIDLError): raise ex pass @@ -6820,7 +6845,7 @@ class Parser(Tokenizer): assert isinstance(scope, IDLScope) # xrange omits the last value. - for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1): + for x in range(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1): builtin = BuiltinTypes[x] name = builtin.name typedef = IDLTypedef(BuiltinLocation(""), scope, builtin, name) @@ -6961,14 +6986,14 @@ def main(): f = open(fullPath, 'rb') lines = f.readlines() f.close() - print fullPath + print(fullPath) parser.parse(''.join(lines), fullPath) parser.finish() - except WebIDLError, e: + except WebIDLError as e: if options.verbose_errors: traceback.print_exc() else: - print e + print(e) if __name__ == '__main__': main() diff --git a/dom/bindings/parser/runtests.py b/dom/bindings/parser/runtests.py index 33bb59f8ab..3947ede222 100644 --- a/dom/bindings/parser/runtests.py +++ b/dom/bindings/parser/runtests.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import os, sys import glob import argparse @@ -22,22 +23,22 @@ class TestHarness(object): def finish(self): if self.verbose or self.printed_intro: - print "Finished test %s" % self.test + print("Finished test %s" % self.test) def maybe_print_intro(self): if not self.printed_intro: - print "Starting test %s" % self.test + print("Starting test %s" % self.test) self.printed_intro = True def test_pass(self, msg): self.passed += 1 if self.verbose: - print "TEST-PASS | %s" % msg + print("TEST-PASS | %s" % msg) def test_fail(self, msg): self.maybe_print_intro() self.failures.append(msg) - print "TEST-UNEXPECTED-FAIL | %s" % msg + print("TEST-UNEXPECTED-FAIL | %s" % msg) def ok(self, condition, msg): if condition: @@ -68,7 +69,7 @@ def run_tests(tests, verbose): harness.start() try: _test.WebIDLTest.__call__(WebIDL.Parser(), harness) - except Exception, ex: + except Exception as ex: harness.test_fail("Unhandled exception in test %s: %s" % (testpath, ex)) traceback.print_exc() @@ -79,15 +80,15 @@ def run_tests(tests, verbose): failed_tests.append((test, harness.failures)) if verbose or failed_tests: - print - print 'Result summary:' - print 'Successful: %d' % all_passed - print 'Unexpected: %d' % \ - sum(len(failures) for _, failures in failed_tests) + print() + print('Result summary:') + print('Successful: %d' % all_passed) + print('Unexpected: %d' % \ + sum(len(failures) for _, failures in failed_tests)) for test, failures in failed_tests: - print '%s:' % test + print('%s:' % test) for failure in failures: - print 'TEST-UNEXPECTED-FAIL | %s' % failure + print('TEST-UNEXPECTED-FAIL | %s' % failure) def get_parser(): usage = """%(prog)s [OPTIONS] [TESTS] diff --git a/dom/bindings/parser/tests/test_attr.py b/dom/bindings/parser/tests/test_attr.py index ad7aabc191..35f680aaa8 100644 --- a/dom/bindings/parser/tests/test_attr.py +++ b/dom/bindings/parser/tests/test_attr.py @@ -133,7 +133,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should not allow [SetterThrows] on readonly attributes") @@ -146,7 +146,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should spell [Throws] correctly") @@ -159,7 +159,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should not allow [SameObject] on attributes not of interface type") @@ -172,6 +172,6 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(not threw, "Should allow [SameObject] on attributes of interface type") diff --git a/dom/bindings/parser/tests/test_cereactions.py b/dom/bindings/parser/tests/test_cereactions.py index 2f9397d903..d7ef94b079 100644 --- a/dom/bindings/parser/tests/test_cereactions.py +++ b/dom/bindings/parser/tests/test_cereactions.py @@ -38,7 +38,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, e: + except Exception as e: harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e) threw = True @@ -52,7 +52,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, e: + except Exception as e: harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e) threw = True diff --git a/dom/bindings/parser/tests/test_conditional_dictionary_member.py b/dom/bindings/parser/tests/test_conditional_dictionary_member.py index 433b7e501a..066300e8bb 100644 --- a/dom/bindings/parser/tests/test_conditional_dictionary_member.py +++ b/dom/bindings/parser/tests/test_conditional_dictionary_member.py @@ -44,7 +44,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, exception: + except Exception as exception: pass harness.ok(exception, "Should have thrown.") @@ -70,7 +70,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, exception: + except Exception as exception: pass harness.ok(exception, "Should have thrown (2).") @@ -100,7 +100,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, exception: + except Exception as exception: pass harness.ok(exception, "Should have thrown (3).") diff --git a/dom/bindings/parser/tests/test_constructor.py b/dom/bindings/parser/tests/test_constructor.py index fb651c08d2..3dad20c8fb 100644 --- a/dom/bindings/parser/tests/test_constructor.py +++ b/dom/bindings/parser/tests/test_constructor.py @@ -32,7 +32,7 @@ def WebIDLTest(parser, harness): harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value") harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures") - sigpairs = zip(method.signatures(), signatures) + sigpairs = list(zip(method.signatures(), signatures)) for (gotSignature, expectedSignature) in sigpairs: (gotRetType, gotArgs) = gotSignature (expectedRetType, expectedArgs) = expectedSignature diff --git a/dom/bindings/parser/tests/test_deduplicate.py b/dom/bindings/parser/tests/test_deduplicate.py index 6249d36fb8..3cc1ffecf6 100644 --- a/dom/bindings/parser/tests/test_deduplicate.py +++ b/dom/bindings/parser/tests/test_deduplicate.py @@ -11,5 +11,5 @@ def WebIDLTest(parser, harness): # There should be no duplicate interfaces in the result. expectedNames = sorted(['Foo', 'Bar']) - actualNames = sorted(map(lambda iface: iface.identifier.name, results)) + actualNames = sorted([iface.identifier.name for iface in results]) harness.check(actualNames, expectedNames, "Parser shouldn't output duplicate names.") diff --git a/dom/bindings/parser/tests/test_empty_sequence_default_value.py b/dom/bindings/parser/tests/test_empty_sequence_default_value.py index 350ae72f02..a713266c88 100644 --- a/dom/bindings/parser/tests/test_empty_sequence_default_value.py +++ b/dom/bindings/parser/tests/test_empty_sequence_default_value.py @@ -10,7 +10,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Constant cannot have [] as a default value") diff --git a/dom/bindings/parser/tests/test_enum.py b/dom/bindings/parser/tests/test_enum.py index 8622893918..a647fb83c5 100644 --- a/dom/bindings/parser/tests/test_enum.py +++ b/dom/bindings/parser/tests/test_enum.py @@ -26,7 +26,7 @@ def WebIDLTest(parser, harness): enum = results[0] harness.check(enum.identifier.QName(), "::TestEnum", "Enum has the right QName") harness.check(enum.identifier.name, "TestEnum", "Enum has the right name") - harness.check(enum.values(), ["", "foo", "bar"], "Enum has the right values") + harness.check(list(enum.values()), ["", "foo", "bar"], "Enum has the right values") iface = results[1] diff --git a/dom/bindings/parser/tests/test_error_colno.py b/dom/bindings/parser/tests/test_error_colno.py index ca0674aec0..7afd15513c 100644 --- a/dom/bindings/parser/tests/test_error_colno.py +++ b/dom/bindings/parser/tests/test_error_colno.py @@ -8,7 +8,7 @@ def WebIDLTest(parser, harness): try: parser.parse(input) results = parser.finish() - except WebIDL.WebIDLError, e: + except WebIDL.WebIDLError as e: threw = True lines = str(e).split('\n') diff --git a/dom/bindings/parser/tests/test_error_lineno.py b/dom/bindings/parser/tests/test_error_lineno.py index f11222e7a4..70bb188368 100644 --- a/dom/bindings/parser/tests/test_error_lineno.py +++ b/dom/bindings/parser/tests/test_error_lineno.py @@ -14,7 +14,7 @@ interface ?""" try: parser.parse(input) results = parser.finish() - except WebIDL.WebIDLError, e: + except WebIDL.WebIDLError as e: threw = True lines = str(e).split('\n') diff --git a/dom/bindings/parser/tests/test_exposed_extended_attribute.py b/dom/bindings/parser/tests/test_exposed_extended_attribute.py index 48957098bf..a6c04e30ca 100644 --- a/dom/bindings/parser/tests/test_exposed_extended_attribute.py +++ b/dom/bindings/parser/tests/test_exposed_extended_attribute.py @@ -124,7 +124,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown on invalid Exposed value on interface.") @@ -140,7 +140,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown on invalid Exposed value on attribute.") @@ -156,7 +156,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown on invalid Exposed value on operation.") @@ -172,7 +172,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown on invalid Exposed value on constant.") @@ -192,7 +192,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown on member exposed where its interface is not.") @@ -216,7 +216,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown on LHS of implements being exposed where RHS is not.") diff --git a/dom/bindings/parser/tests/test_float_types.py b/dom/bindings/parser/tests/test_float_types.py index 718f09c114..b7325cf9d2 100644 --- a/dom/bindings/parser/tests/test_float_types.py +++ b/dom/bindings/parser/tests/test_float_types.py @@ -68,7 +68,7 @@ def WebIDLTest(parser, harness): long m(float arg); }; """) - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "[LenientFloat] only allowed on void methods") @@ -81,7 +81,7 @@ def WebIDLTest(parser, harness): void m(unrestricted float arg); }; """) - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args") @@ -94,7 +94,7 @@ def WebIDLTest(parser, harness): void m(sequence arg); }; """) - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)") @@ -107,7 +107,7 @@ def WebIDLTest(parser, harness): void m((unrestricted float or FloatTypes) arg); }; """) - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)") @@ -120,6 +120,6 @@ def WebIDLTest(parser, harness): readonly attribute float foo; }; """) - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "[LenientFloat] only allowed on writable attributes") diff --git a/dom/bindings/parser/tests/test_identifier_conflict.py b/dom/bindings/parser/tests/test_identifier_conflict.py index b510a30c04..0e9a6654aa 100644 --- a/dom/bindings/parser/tests/test_identifier_conflict.py +++ b/dom/bindings/parser/tests/test_identifier_conflict.py @@ -9,7 +9,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() harness.ok(False, "Should fail to parse") - except Exception, e: + except Exception as e: harness.ok("Name collision" in e.message, "Should have name collision for interface") @@ -21,7 +21,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() harness.ok(False, "Should fail to parse") - except Exception, e: + except Exception as e: harness.ok("Name collision" in e.message, "Should have name collision for dictionary") @@ -33,7 +33,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() harness.ok(False, "Should fail to parse") - except Exception, e: + except Exception as e: harness.ok("Multiple unresolvable definitions" in e.message, "Should have name collision for dictionary") diff --git a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py index ee5d870c20..72aa7617b8 100644 --- a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py +++ b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py @@ -37,10 +37,10 @@ def WebIDLTest(parser, harness): p.finish() harness.ok(False, prefix + " - Interface passed when should've failed") - except WebIDL.WebIDLError, e: + except WebIDL.WebIDLError as e: harness.ok(True, prefix + " - Interface failed as expected") - except Exception, e: + except Exception as e: harness.ok(False, prefix + " - Interface failed but not as a WebIDLError exception: %s" % e) diff --git a/dom/bindings/parser/tests/test_method.py b/dom/bindings/parser/tests/test_method.py index cf7f1b40d7..2f5f4b0b2b 100644 --- a/dom/bindings/parser/tests/test_method.py +++ b/dom/bindings/parser/tests/test_method.py @@ -59,7 +59,7 @@ def WebIDLTest(parser, harness): harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value") harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures") - sigpairs = zip(method.signatures(), signatures) + sigpairs = list(zip(method.signatures(), signatures)) for (gotSignature, expectedSignature) in sigpairs: (gotRetType, gotArgs) = gotSignature (expectedRetType, expectedArgs) = expectedSignature @@ -121,7 +121,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(not threw, "Should allow integer to float type corecion") @@ -134,7 +134,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should not allow [GetterThrows] on methods") @@ -147,7 +147,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should not allow [SetterThrows] on methods") @@ -160,7 +160,7 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should spell [Throws] correctly on methods") @@ -173,6 +173,6 @@ def WebIDLTest(parser, harness): }; """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should not allow __noSuchMethod__ methods") diff --git a/dom/bindings/parser/tests/test_mozmap.py b/dom/bindings/parser/tests/test_mozmap.py index 1a36fdd62c..fa852c02a0 100644 --- a/dom/bindings/parser/tests/test_mozmap.py +++ b/dom/bindings/parser/tests/test_mozmap.py @@ -33,7 +33,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") diff --git a/dom/bindings/parser/tests/test_namespace.py b/dom/bindings/parser/tests/test_namespace.py index 74533a1770..62edb270c6 100644 --- a/dom/bindings/parser/tests/test_namespace.py +++ b/dom/bindings/parser/tests/test_namespace.py @@ -70,7 +70,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -85,7 +85,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -104,7 +104,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -123,7 +123,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -142,7 +142,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -161,7 +161,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -180,7 +180,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -199,7 +199,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -218,6 +218,6 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") diff --git a/dom/bindings/parser/tests/test_unenumerable_own_properties.py b/dom/bindings/parser/tests/test_unenumerable_own_properties.py index d017d5ce09..d28cc1ec05 100644 --- a/dom/bindings/parser/tests/test_unenumerable_own_properties.py +++ b/dom/bindings/parser/tests/test_unenumerable_own_properties.py @@ -24,7 +24,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -39,7 +39,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") @@ -59,6 +59,6 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception, x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown.") diff --git a/dom/bindings/parser/tests/test_unforgeable.py b/dom/bindings/parser/tests/test_unforgeable.py index 3787e8c6af..44a168670e 100644 --- a/dom/bindings/parser/tests/test_unforgeable.py +++ b/dom/bindings/parser/tests/test_unforgeable.py @@ -111,7 +111,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown when shadowing unforgeable attribute on " @@ -130,7 +130,7 @@ def WebIDLTest(parser, harness): """) results = parser.finish() - except Exception,x: + except Exception as x: threw = True harness.ok(threw, "Should have thrown when shadowing unforgeable operation on " diff --git a/dom/bindings/parser/tests/test_union.py b/dom/bindings/parser/tests/test_union.py index 9c4f2a56ab..aa538a97da 100644 --- a/dom/bindings/parser/tests/test_union.py +++ b/dom/bindings/parser/tests/test_union.py @@ -17,10 +17,10 @@ def combinations(iterable, r): n = len(pool) if r > n: return - indices = range(r) + indices = list(range(r)) yield tuple(pool[i] for i in indices) while True: - for i in reversed(range(r)): + for i in reversed(list(range(r))): if indices[i] != i + n - r: break else: @@ -41,7 +41,7 @@ def combinations_with_replacement(iterable, r): indices = [0] * r yield tuple(pool[i] for i in indices) while True: - for i in reversed(range(r)): + for i in reversed(list(range(r))): if indices[i] != n - 1: break else: @@ -125,7 +125,7 @@ def WebIDLTest(parser, harness): # Create a list of tuples containing the name of the type as a string and # the parsed IDL type. - types = zip(types, (a.type for a in iface.members)) + types = list(zip(types, (a.type for a in iface.members))) validUnionTypes = chain(unionTypes(combinations(types, 2), typesAreDistinguishable), unionTypes(combinations(types, 3), typesAreDistinguishable)) diff --git a/dom/browser-element/mochitest/createNewTest.py b/dom/browser-element/mochitest/createNewTest.py index 309ff95344..bd0f317280 100644 --- a/dom/browser-element/mochitest/createNewTest.py +++ b/dom/browser-element/mochitest/createNewTest.py @@ -2,7 +2,6 @@ This script requires Python 2.7.""" -from __future__ import print_function import sys import os @@ -59,9 +58,9 @@ def add_to_ini(filename, test, support_file=None): places in the file. """ - lines_to_write = ['[{0}]'.format(test)] + lines_to_write = ['[{}]'.format(test)] if support_file: - lines_to_write += ['support-files = {0}'.format(support_file)] + lines_to_write += ['support-files = {}'.format(support_file)] lines_to_write += [''] with open(filename, 'a') as f: f.write('\n'.join(lines_to_write)) @@ -73,7 +72,7 @@ def add_to_ini(filename, test, support_file=None): return # Count the number of lines in the file - with open(filename, 'r') as f: + with open(filename) as f: num_lines = len(f.readlines()) try: @@ -81,7 +80,7 @@ def add_to_ini(filename, test, support_file=None): '+%d' % (num_lines - len(lines_to_write) + 2), filename]) except Exception as e: - print_fill("Error opening $EDITOR: {0}.".format(e)) + print_fill("Error opening $EDITOR: {}.".format(e)) print() print_fill("""\ Please open {filename} and move the filenames at the bottom of the diff --git a/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py b/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py index 919ba23280..4f51f034e6 100644 --- a/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py +++ b/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py @@ -16,7 +16,7 @@ def ReadLocalFile(include): data = None try: - f = open(filePath, 'r') + f = open(filePath) data = f.read() except: pass diff --git a/dom/media/test/external/external_media_harness/__init__.py b/dom/media/test/external/external_media_harness/__init__.py index 906473f0bc..7ea101bbfe 100644 --- a/dom/media/test/external/external_media_harness/__init__.py +++ b/dom/media/test/external/external_media_harness/__init__.py @@ -2,4 +2,4 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from runtests import cli +from .runtests import cli diff --git a/dom/media/test/external/external_media_harness/runtests.py b/dom/media/test/external/external_media_harness/runtests.py index 08d1a323b1..9762a16449 100644 --- a/dom/media/test/external/external_media_harness/runtests.py +++ b/dom/media/test/external/external_media_harness/runtests.py @@ -16,7 +16,7 @@ from marionette_harness import ( from marionette_harness.runtests import MarionetteHarness, cli as mn_cli import external_media_tests -from testcase import MediaTestCase +from .testcase import MediaTestCase from external_media_tests.media_utils.video_puppeteer import debug_script diff --git a/dom/media/test/external/external_media_tests/media_utils/video_puppeteer.py b/dom/media/test/external/external_media_tests/media_utils/video_puppeteer.py index b904267dd4..475b4e7812 100644 --- a/dom/media/test/external/external_media_tests/media_utils/video_puppeteer.py +++ b/dom/media/test/external/external_media_tests/media_utils/video_puppeteer.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function from collections import namedtuple from time import clock, sleep @@ -181,7 +182,7 @@ class VideoPuppeteer(object): played_ranges.end(0) > 0.0 ) except Exception as e: - print ('Got exception {}'.format(e)) + print(('Got exception {}'.format(e))) return False def playback_done(self): @@ -408,7 +409,7 @@ class VideoPuppeteer(object): for field in self._last_seen_video_state._fields: # For compatibility with different test environments we force ascii field_ascii = ( - unicode(getattr(self._last_seen_video_state, field)) + str(getattr(self._last_seen_video_state, field)) .encode('ascii','replace')) messages += [('\t{}: {}'.format(field, field_ascii))] messages += '}' diff --git a/dom/media/test/external/external_media_tests/media_utils/youtube_puppeteer.py b/dom/media/test/external/external_media_tests/media_utils/youtube_puppeteer.py index e42bbcc875..3ec9ec9208 100644 --- a/dom/media/test/external/external_media_tests/media_utils/youtube_puppeteer.py +++ b/dom/media/test/external/external_media_tests/media_utils/youtube_puppeteer.py @@ -12,7 +12,7 @@ from marionette_driver import By, expected, Wait from marionette_driver.errors import TimeoutException, NoSuchElementException from marionette_harness import Marionette -from video_puppeteer import VideoPuppeteer, VideoException +from .video_puppeteer import VideoPuppeteer, VideoException from external_media_tests.utils import verbose_until @@ -489,7 +489,7 @@ class YouTubePuppeteer(VideoPuppeteer): for field in self._last_seen_player_state._fields: # For compatibility with different test environments we force ascii field_ascii = ( - unicode(getattr(self._last_seen_player_state, field)) + str(getattr(self._last_seen_player_state, field)) .encode('ascii', 'replace')) messages += [('\t{}: {}'.format(field, field_ascii))] messages += '}' diff --git a/dom/media/test/external/external_media_tests/playback/test_eme_playback.py b/dom/media/test/external/external_media_tests/playback/test_eme_playback.py index 9c7eb67258..373ede2462 100644 --- a/dom/media/test/external/external_media_tests/playback/test_eme_playback.py +++ b/dom/media/test/external/external_media_tests/playback/test_eme_playback.py @@ -1,18 +1,18 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -from external_media_harness.testcase import ( - MediaTestCase, - VideoPlaybackTestsMixin, - EMESetupMixin -) - - -class TestEMEPlayback(MediaTestCase, VideoPlaybackTestsMixin, EMESetupMixin): - - def setUp(self): - super(TestEMEPlayback, self).setUp() - self.check_eme_system() - - # Tests are implemented in VideoPlaybackTestsMixin +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from external_media_harness.testcase import ( + MediaTestCase, + VideoPlaybackTestsMixin, + EMESetupMixin +) + + +class TestEMEPlayback(MediaTestCase, VideoPlaybackTestsMixin, EMESetupMixin): + + def setUp(self): + super(TestEMEPlayback, self).setUp() + self.check_eme_system() + + # Tests are implemented in VideoPlaybackTestsMixin diff --git a/dom/media/test/external/mach_commands.py b/dom/media/test/external/mach_commands.py index e309f3c55e..487a7d21fe 100644 --- a/dom/media/test/external/mach_commands.py +++ b/dom/media/test/external/mach_commands.py @@ -45,7 +45,7 @@ def run_external_media_test(tests, testtype=None, topsrcdir=None, **kwargs): args = Namespace(tests=tests) - for k, v in kwargs.iteritems(): + for k, v in kwargs.items(): setattr(args, k, v) parser.verify_usage(args) diff --git a/dom/media/test/graph_latency.py b/dom/media/test/graph_latency.py index 576f58d864..f0df270c35 100644 --- a/dom/media/test/graph_latency.py +++ b/dom/media/test/graph_latency.py @@ -7,6 +7,7 @@ # needs matplotlib (sudo aptitude install python-matplotlib) +from __future__ import print_function import matplotlib.pyplot as plt from matplotlib import rc import sys @@ -22,10 +23,10 @@ def compute_sum(data): out = ([],[]) for i in data: - if i[0] not in last_values.keys(): + if i[0] not in list(last_values.keys()): last_values[i[0]] = 0 last_values[i[0]] = float(i[3]) - print last_values + print(last_values) out[0].append(i[2]) out[1].append(sum(last_values.values())) return out @@ -59,12 +60,12 @@ if len(sys.argv) == 3: name = sys.argv[1] channels = int(sys.argv[2]) else: - print sys.argv[0] + "latency_log" + print(sys.argv[0] + "latency_log") try: f = open(sys.argv[1]) except: - print "cannot open " + name + print("cannot open " + name) raw_lines = f.readlines() lines = clean_data(raw_lines) @@ -76,7 +77,7 @@ for tupl in data: name = tupl[0] if tupl[1] != 0: name = name+tupl[1] - if name not in final_data.keys(): + if name not in list(final_data.keys()): final_data[name] = ([], []) # sanity-check values if float(tupl[3]) < 10*1000: diff --git a/dom/security/test/csp/file_websocket_self_wsh.py b/dom/security/test/csp/file_websocket_self_wsh.py index 5fe508a910..0ae161bff1 100644 --- a/dom/security/test/csp/file_websocket_self_wsh.py +++ b/dom/security/test/csp/file_websocket_self_wsh.py @@ -1,7 +1,7 @@ -from mod_pywebsocket import msgutil - -def web_socket_do_extra_handshake(request): - pass - -def web_socket_transfer_data(request): - pass +from mod_pywebsocket import msgutil + +def web_socket_do_extra_handshake(request): + pass + +def web_socket_transfer_data(request): + pass diff --git a/gfx/angle/src/commit_id.py b/gfx/angle/src/commit_id.py index bbdb810ce0..fcae35797c 100755 --- a/gfx/angle/src/commit_id.py +++ b/gfx/angle/src/commit_id.py @@ -1,3 +1,4 @@ +from __future__ import print_function import subprocess as sp import sys import os diff --git a/gfx/angle/src/common/Float16ToFloat32.py b/gfx/angle/src/common/Float16ToFloat32.py index 7705f7b619..04af0dff3e 100755 --- a/gfx/angle/src/common/Float16ToFloat32.py +++ b/gfx/angle/src/common/Float16ToFloat32.py @@ -9,6 +9,7 @@ #include "common/mathutil.h" +from __future__ import print_function def convertMantissa(i): if i == 0: return 0 @@ -44,7 +45,7 @@ def convertOffset(i): else: return 1024 -print """// +print("""// // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -54,27 +55,27 @@ print """// namespace gl { -""" +""") -print "const static unsigned g_mantissa[2048] = {" +print("const static unsigned g_mantissa[2048] = {") for i in range(0, 2048): - print " %#010x," % convertMantissa(i) -print "};\n" + print(" %#010x," % convertMantissa(i)) +print("};\n") -print "const static unsigned g_exponent[64] = {" +print("const static unsigned g_exponent[64] = {") for i in range(0, 64): - print " %#010x," % convertExponent(i) -print "};\n" + print(" %#010x," % convertExponent(i)) +print("};\n") -print "const static unsigned g_offset[64] = {" +print("const static unsigned g_offset[64] = {") for i in range(0, 64): - print " %#010x," % convertOffset(i) -print "};\n" + print(" %#010x," % convertOffset(i)) +print("};\n") -print """float float16ToFloat32(unsigned short h) +print("""float float16ToFloat32(unsigned short h) { unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10]; return bitCast(i32); } } -""" +""") diff --git a/gfx/angle/src/libANGLE/renderer/angle_format.py b/gfx/angle/src/libANGLE/renderer/angle_format.py index e46bc7dba9..c0be62baec 100755 --- a/gfx/angle/src/libANGLE/renderer/angle_format.py +++ b/gfx/angle/src/libANGLE/renderer/angle_format.py @@ -39,7 +39,7 @@ def load_with_override(override_path): results = load_forward_table(map_path) overrides = load_json(override_path) - for k, v in overrides.iteritems(): + for k, v in overrides.items(): results[k] = v return results diff --git a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py index 21b22803b9..282dbf4496 100755 --- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py +++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py @@ -13,6 +13,7 @@ # 11_0: https://msdn.microsoft.com/en-us/library/windows/desktop/ff471325.aspx # 11_1: https://msdn.microsoft.com/en-us/library/windows/desktop/hh404483.aspx +from __future__ import print_function import sys import json @@ -141,7 +142,7 @@ def do_format(format_data): 'depthStencil': macro_prefix + 'DS' } - for format_name, format_support in sorted(format_data.iteritems()): + for format_name, format_support in sorted(format_data.items()): always_supported = set() never_supported = set() @@ -152,7 +153,7 @@ def do_format(format_data): fl_10_0_check_10_1_supported = set() fl_10_0_check_11_0_supported = set() - for json_flag, support in format_support.iteritems(): + for json_flag, support in format_support.items(): d3d_flag = [json_flag_to_d3d[json_flag]] @@ -182,7 +183,7 @@ def do_format(format_data): elif support == '11_0check': fl_11_0_check.update(d3d_flag) else: - print("Data specification error: " + support) + print(("Data specification error: " + support)) sys.exit(1) for feature_level in ['10_0', '10_1', '11_0']: diff --git a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py index 981a77f51a..7cca2c22c2 100755 --- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py +++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py @@ -158,8 +158,8 @@ def get_swizzle_format_id(internal_format, angle_format): raise ValueError('no bits information for determining swizzleformat for format: ' + internal_format) bits = angle_format['bits'] - max_component_bits = max(bits.itervalues()) - channels_different = not all([component_bits == bits.itervalues().next() for component_bits in bits.itervalues()]) + max_component_bits = max(bits.values()) + channels_different = not all([component_bits == next(bits.values()) for component_bits in bits.values()]) # The format itself can be used for swizzles if it can be accessed as a render target and # sampled and the bit count for all 4 channels is the same. @@ -261,7 +261,7 @@ def json_to_table_data(internal_format, format_name, prefix, json): "condition": prefix, } - for k, v in json.iteritems(): + for k, v in json.items(): parsed[k] = v # Derived values. @@ -280,15 +280,15 @@ def parse_json_angle_format_case(format_name, angle_format, json_data): support_test = None fallback = None - for k, v in angle_format.iteritems(): + for k, v in angle_format.items(): if k == "FL10Plus": assert support_test is None support_test = "OnlyFL10Plus(deviceCaps)" - for k2, v2 in v.iteritems(): + for k2, v2 in v.items(): supported_case[k2] = v2 elif k == "FL9_3": split = True - for k2, v2 in v.iteritems(): + for k2, v2 in v.items(): unsupported_case[k2] = v2 elif k == "supportTest": assert support_test is None @@ -312,7 +312,7 @@ def parse_json_angle_format_case(format_name, angle_format, json_data): def parse_json_into_switch_angle_format_string(json_map, json_data): table_data = '' - for internal_format, format_name in sorted(json_map.iteritems()): + for internal_format, format_name in sorted(json_map.items()): if format_name not in json_data: continue diff --git a/gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py b/gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py index 7356fc4149..d6a8357ee5 100755 --- a/gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py +++ b/gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py @@ -153,7 +153,7 @@ def get_component_type(format_id): def get_channel_tokens(format_id): r = re.compile(r'([ABDGLRS][\d]+)') - return filter(r.match, r.split(format_id)) + return list(filter(r.match, r.split(format_id))) def get_channels(format_id): channels = '' @@ -183,7 +183,7 @@ def json_to_table_data(format_id, json, angle_to_gl): "id": format_id, } - for k, v in json.iteritems(): + for k, v in json.items(): parsed[k] = v if "glInternalFormat" not in parsed: @@ -227,7 +227,7 @@ def gen_enum_string(all_angle): gl_to_angle = angle_format.load_forward_table('angle_format_map.json') angle_to_gl = angle_format.load_inverse_table('angle_format_map.json') json_data = angle_format.load_json('angle_format_data.json') -all_angle = angle_to_gl.keys() +all_angle = list(angle_to_gl.keys()) angle_format_cases = parse_json_into_angle_format_switch_string( all_angle, json_data, angle_to_gl) diff --git a/gfx/angle/src/libANGLE/renderer/gen_load_functions_table.py b/gfx/angle/src/libANGLE/renderer/gen_load_functions_table.py index eb3e4c5bf0..2ba474680a 100755 --- a/gfx/angle/src/libANGLE/renderer/gen_load_functions_table.py +++ b/gfx/angle/src/libANGLE/renderer/gen_load_functions_table.py @@ -107,7 +107,7 @@ def get_load_func(func_name, type_functions): snippet += "{\n" snippet += " switch (type)\n" snippet += " {\n" - for gl_type, load_function in sorted(type_functions.iteritems()): + for gl_type, load_function in sorted(type_functions.items()): snippet += " case " + gl_type + ":\n" requiresConversion = str('LoadToNative<' not in load_function).lower() snippet += " return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n" @@ -127,13 +127,13 @@ def get_unknown_load_func(angle_to_type_map, internal_format): def parse_json(json_data): table_data = '' load_functions_data = '' - for internal_format, angle_to_type_map in sorted(json_data.iteritems()): + for internal_format, angle_to_type_map in sorted(json_data.items()): s = ' ' table_data += s + 'case ' + internal_format + ':\n' - do_switch = len(angle_to_type_map) > 1 or angle_to_type_map.keys()[0] != angle_format_unknown + do_switch = len(angle_to_type_map) > 1 or list(angle_to_type_map.keys())[0] != angle_format_unknown if do_switch: table_data += s + '{\n' @@ -142,7 +142,7 @@ def parse_json(json_data): table_data += s + '{\n' s += ' ' - for angle_format, type_functions in sorted(angle_to_type_map.iteritems()): + for angle_format, type_functions in sorted(angle_to_type_map.items()): if angle_format == angle_format_unknown: continue @@ -154,7 +154,7 @@ def parse_json(json_data): table_data += s + ' return ' + func_name + ';\n' if angle_format_unknown in angle_to_type_map: - for gl_type, load_function in angle_to_type_map[angle_format_unknown].iteritems(): + for gl_type, load_function in angle_to_type_map[angle_format_unknown].items(): if gl_type not in type_functions: type_functions[gl_type] = load_function diff --git a/gfx/gl/GLParseRegistryXML.py b/gfx/gl/GLParseRegistryXML.py index 60daca6e56..0519cbfc0f 100755 --- a/gfx/gl/GLParseRegistryXML.py +++ b/gfx/gl/GLParseRegistryXML.py @@ -22,6 +22,7 @@ ################################################################################ # includes +from __future__ import print_function import os import sys import xml.etree.ElementTree @@ -38,7 +39,7 @@ class GLConstHeader: def write(self, arg): if isinstance(arg, list): self.f.write('\n'.join(arg) + '\n') - elif isinstance(arg, (int, long)): + elif isinstance(arg, int): self.f.write('\n' * arg) else: self.f.write(str(arg) + '\n') @@ -137,7 +138,7 @@ class GLDatabase: xmlPath = getXMLDir() + path if not os.path.isfile(xmlPath): - print 'missing file "' + xmlPath + '"' + print('missing file "' + xmlPath + '"') return False tree = xml.etree.ElementTree.parse(xmlPath) @@ -186,7 +187,7 @@ class GLDatabase: headerFile = GLConstHeader(f) headerFile.formatFileBegin() - constNames = self.consts.keys() + constNames = list(self.consts.keys()) constNames.sort() for lib in GLDatabase.LIBS: diff --git a/gfx/harfbuzz/src/check-c-linkage-decls.py b/gfx/harfbuzz/src/check-c-linkage-decls.py index 3c206115a9..80395b38e6 100644 --- a/gfx/harfbuzz/src/check-c-linkage-decls.py +++ b/gfx/harfbuzz/src/check-c-linkage-decls.py @@ -1,36 +1,37 @@ -#!/usr/bin/env python3 - -import sys, os - -srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) -base_srcdir = os.getenv ('base_srcdir', srcdir) - -os.chdir (srcdir) - -def removeprefix(s): - abs_path = os.path.join(base_srcdir, s) - return os.path.relpath(abs_path, srcdir) - - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] -HBSOURCES = [ - removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () -] or [ - x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) -] -stat = 0 - -for x in HBHEADERS: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if ('HB_BEGIN_DECLS' not in content) or ('HB_END_DECLS' not in content): - print ('Ouch, file %s does not have HB_BEGIN_DECLS / HB_END_DECLS, but it should' % x) - stat = 1 - -for x in HBSOURCES: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if ('HB_BEGIN_DECLS' in content) or ('HB_END_DECLS' in content): - print ('Ouch, file %s has HB_BEGIN_DECLS / HB_END_DECLS, but it shouldn\'t' % x) - stat = 1 - -sys.exit (stat) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os + +srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) +base_srcdir = os.getenv ('base_srcdir', srcdir) + +os.chdir (srcdir) + +def removeprefix(s): + abs_path = os.path.join(base_srcdir, s) + return os.path.relpath(abs_path, srcdir) + + +HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ + [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] +HBSOURCES = [ + removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () +] or [ + x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) +] +stat = 0 + +for x in HBHEADERS: + with open (x, 'r', encoding='utf-8') as f: content = f.read () + if ('HB_BEGIN_DECLS' not in content) or ('HB_END_DECLS' not in content): + print(('Ouch, file %s does not have HB_BEGIN_DECLS / HB_END_DECLS, but it should' % x)) + stat = 1 + +for x in HBSOURCES: + with open (x, 'r', encoding='utf-8') as f: content = f.read () + if ('HB_BEGIN_DECLS' in content) or ('HB_END_DECLS' in content): + print(('Ouch, file %s has HB_BEGIN_DECLS / HB_END_DECLS, but it shouldn\'t' % x)) + stat = 1 + +sys.exit (stat) diff --git a/gfx/harfbuzz/src/check-externs.py b/gfx/harfbuzz/src/check-externs.py index 3905cc4fc6..facf559670 100644 --- a/gfx/harfbuzz/src/check-externs.py +++ b/gfx/harfbuzz/src/check-externs.py @@ -1,20 +1,21 @@ -#!/usr/bin/env python3 - -import sys, os, re - -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] - -stat = 0 - -print ('Checking that all public symbols are exported with HB_EXTERN') -for x in HBHEADERS: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - for s in re.findall (r'\n.+\nhb_.+\n', content): - if not s.startswith ('\nHB_EXTERN '): - print ('failure on:', s) - stat = 1 - -sys.exit (stat) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os, re + +os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) + +HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ + [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] + +stat = 0 + +print ('Checking that all public symbols are exported with HB_EXTERN') +for x in HBHEADERS: + with open (x, 'r', encoding='utf-8') as f: content = f.read () + for s in re.findall (r'\n.+\nhb_.+\n', content): + if not s.startswith ('\nHB_EXTERN '): + print(('failure on:', s)) + stat = 1 + +sys.exit (stat) diff --git a/gfx/harfbuzz/src/check-header-guards.py b/gfx/harfbuzz/src/check-header-guards.py index ba7d42fbac..a3de9c5184 100644 --- a/gfx/harfbuzz/src/check-header-guards.py +++ b/gfx/harfbuzz/src/check-header-guards.py @@ -1,34 +1,35 @@ -#!/usr/bin/env python3 - -import sys, os, re - -srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) -base_srcdir = os.getenv ('base_srcdir', srcdir) - -os.chdir (srcdir) - -def removeprefix(s): - abs_path = os.path.join(base_srcdir, s) - return os.path.relpath(abs_path, srcdir) - - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] -HBSOURCES = [ - removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () -] or [ - x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) -] - - -stat = 0 - -for x in HBHEADERS + HBSOURCES: - if not x.endswith ('h') or x == 'hb-gobject-structs.h': continue - tag = x.upper ().replace ('.', '_').replace ('-', '_').replace(os.path.sep, '_').replace('/', '_') - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if len (re.findall (tag + r'\b', content)) != 3: - print ('Ouch, header file %s does not have correct preprocessor guards. Expected: %s' % (x, tag)) - stat = 1 - -sys.exit (stat) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os, re + +srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) +base_srcdir = os.getenv ('base_srcdir', srcdir) + +os.chdir (srcdir) + +def removeprefix(s): + abs_path = os.path.join(base_srcdir, s) + return os.path.relpath(abs_path, srcdir) + + +HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ + [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] +HBSOURCES = [ + removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () +] or [ + x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) +] + + +stat = 0 + +for x in HBHEADERS + HBSOURCES: + if not x.endswith ('h') or x == 'hb-gobject-structs.h': continue + tag = x.upper ().replace ('.', '_').replace ('-', '_').replace(os.path.sep, '_').replace('/', '_') + with open (x, 'r', encoding='utf-8') as f: content = f.read () + if len (re.findall (tag + r'\b', content)) != 3: + print(('Ouch, header file %s does not have correct preprocessor guards. Expected: %s' % (x, tag))) + stat = 1 + +sys.exit (stat) diff --git a/gfx/harfbuzz/src/check-includes.py b/gfx/harfbuzz/src/check-includes.py index 2cead7b3f9..829ac835eb 100644 --- a/gfx/harfbuzz/src/check-includes.py +++ b/gfx/harfbuzz/src/check-includes.py @@ -1,51 +1,52 @@ -#!/usr/bin/env python3 - -import sys, os, re - -srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) -base_srcdir = os.getenv ('base_srcdir', srcdir) - -os.chdir (srcdir) - -def removeprefix(s): - abs_path = os.path.join(base_srcdir, s) - return os.path.relpath(abs_path, srcdir) - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] - -HBSOURCES = [ - removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () -] or [ - x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) -] - - -stat = 0 - -print ('Checking that public header files #include "hb-common.h" or "hb.h" first (or none)') -for x in HBHEADERS: - if x == 'hb.h' or x == 'hb-common.h': continue - with open (x, 'r', encoding='utf-8') as f: content = f.read () - first = re.findall (r'#.*include.*', content)[0] - if first not in ['#include "hb.h"', '#include "hb-common.h"']: - print ('failure on %s' % x) - stat = 1 - -print ('Checking that source files #include a private header first (or none)') -for x in HBSOURCES: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - includes = re.findall (r'#.*include.*', content) - if includes: - if not len (re.findall (r'".*\.hh"', includes[0])): - print ('failure on %s' % x) - stat = 1 - -print ('Checking that there is no #include ') -for x in HBHEADERS + HBSOURCES: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if re.findall ('#.*include.*<.*hb', content): - print ('failure on %s' % x) - stat = 1 - -sys.exit (stat) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os, re + +srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) +base_srcdir = os.getenv ('base_srcdir', srcdir) + +os.chdir (srcdir) + +def removeprefix(s): + abs_path = os.path.join(base_srcdir, s) + return os.path.relpath(abs_path, srcdir) + +HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ + [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] + +HBSOURCES = [ + removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () +] or [ + x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) +] + + +stat = 0 + +print ('Checking that public header files #include "hb-common.h" or "hb.h" first (or none)') +for x in HBHEADERS: + if x == 'hb.h' or x == 'hb-common.h': continue + with open (x, 'r', encoding='utf-8') as f: content = f.read () + first = re.findall (r'#.*include.*', content)[0] + if first not in ['#include "hb.h"', '#include "hb-common.h"']: + print(('failure on %s' % x)) + stat = 1 + +print ('Checking that source files #include a private header first (or none)') +for x in HBSOURCES: + with open (x, 'r', encoding='utf-8') as f: content = f.read () + includes = re.findall (r'#.*include.*', content) + if includes: + if not len (re.findall (r'".*\.hh"', includes[0])): + print(('failure on %s' % x)) + stat = 1 + +print ('Checking that there is no #include ') +for x in HBHEADERS + HBSOURCES: + with open (x, 'r', encoding='utf-8') as f: content = f.read () + if re.findall ('#.*include.*<.*hb', content): + print(('failure on %s' % x)) + stat = 1 + +sys.exit (stat) diff --git a/gfx/harfbuzz/src/check-libstdc++.py b/gfx/harfbuzz/src/check-libstdc++.py index 4cfab52d4b..ffa11d245e 100644 --- a/gfx/harfbuzz/src/check-libstdc++.py +++ b/gfx/harfbuzz/src/check-libstdc++.py @@ -1,39 +1,40 @@ -#!/usr/bin/env python3 - -import sys, os, shutil, subprocess - -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) - -libs = os.getenv ('libs', '.libs') - -ldd = os.getenv ('LDD', shutil.which ('ldd')) -if not ldd: - otool = os.getenv ('OTOOL', shutil.which ('otool')) - if otool: - ldd = otool + ' -L' - else: - print ('check-libstdc++.py: \'ldd\' not found; skipping test') - sys.exit (77) - -stat = 0 -tested = False - -# harfbuzz-icu links to libstdc++ because icu does. -for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-gobject', 'harfbuzz-cairo']: - for suffix in ['so', 'dylib']: - so = os.path.join (libs, 'lib%s.%s' % (soname, suffix)) - if not os.path.exists (so): continue - - print ('Checking that we are not linking to libstdc++ or libc++ in %s' % so) - ldd_result = subprocess.check_output (ldd.split() + [so]) - if (b'libstdc++' in ldd_result) or (b'libc++' in ldd_result): - print ('Ouch, %s is linked to libstdc++ or libc++' % so) - stat = 1 - - tested = True - -if not tested: - print ('check-libstdc++.py: libharfbuzz shared library not found; skipping test') - sys.exit (77) - -sys.exit (stat) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os, shutil, subprocess + +os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) + +libs = os.getenv ('libs', '.libs') + +ldd = os.getenv ('LDD', shutil.which ('ldd')) +if not ldd: + otool = os.getenv ('OTOOL', shutil.which ('otool')) + if otool: + ldd = otool + ' -L' + else: + print ('check-libstdc++.py: \'ldd\' not found; skipping test') + sys.exit (77) + +stat = 0 +tested = False + +# harfbuzz-icu links to libstdc++ because icu does. +for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-gobject', 'harfbuzz-cairo']: + for suffix in ['so', 'dylib']: + so = os.path.join (libs, 'lib%s.%s' % (soname, suffix)) + if not os.path.exists (so): continue + + print(('Checking that we are not linking to libstdc++ or libc++ in %s' % so)) + ldd_result = subprocess.check_output (ldd.split() + [so]) + if (b'libstdc++' in ldd_result) or (b'libc++' in ldd_result): + print(('Ouch, %s is linked to libstdc++ or libc++' % so)) + stat = 1 + + tested = True + +if not tested: + print ('check-libstdc++.py: libharfbuzz shared library not found; skipping test') + sys.exit (77) + +sys.exit (stat) diff --git a/gfx/harfbuzz/src/check-static-inits.py b/gfx/harfbuzz/src/check-static-inits.py index 7217f03934..4e5ab1bd86 100644 --- a/gfx/harfbuzz/src/check-static-inits.py +++ b/gfx/harfbuzz/src/check-static-inits.py @@ -1,51 +1,52 @@ -#!/usr/bin/env python3 - -import sys, os, shutil, subprocess, glob, re - -builddir = os.getenv ('builddir', os.path.dirname (__file__)) -libs = os.getenv ('libs', '.libs') - -objdump = os.getenv ('OBJDUMP', shutil.which ('objdump')) -if not objdump: - print ('check-static-inits.py: \'ldd\' not found; skipping test') - sys.exit (77) - -if sys.version_info < (3, 5): - print ('check-static-inits.py: needs python 3.5 for recursive support in glob') - sys.exit (77) - -OBJS = glob.glob (os.path.join (builddir, libs, '**', '*hb*.o'), recursive=True) -if not OBJS: - print ('check-static-inits.py: object files not found; skipping test') - sys.exit (77) - -stat = 0 -tested = 0 - -for obj in OBJS: - result = subprocess.run(objdump.split () + ['-t', obj], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - if result.returncode: - if result.stderr.find (b'not recognized') != -1: - # https://github.com/harfbuzz/harfbuzz/issues/3019 - print ('objdump %s returned "not recognized", skipping' % obj) - continue - print ('objdump %s returned error:\n%s' % (obj, result.stderr.decode ('utf-8'))) - stat = 2 - - result = result.stdout.decode ('utf-8') - - # Checking that no object file has static initializers - for l in re.findall (r'^.*\.[cd]tors.*$', result, re.MULTILINE): - if not re.match (r'.*\b0+\b', l): - print ('Ouch, %s has static initializers/finalizers' % obj) - stat = 1 - - # Checking that no object file has lazy static C++ constructors/destructors or other such stuff - if ('__cxa_' in result) and ('__ubsan_handle' not in result): - print ('Ouch, %s has lazy static C++ constructors/destructors or other such stuff' % obj) - stat = 1 - - tested += 1 - -sys.exit (stat if tested else 77) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os, shutil, subprocess, glob, re + +builddir = os.getenv ('builddir', os.path.dirname (__file__)) +libs = os.getenv ('libs', '.libs') + +objdump = os.getenv ('OBJDUMP', shutil.which ('objdump')) +if not objdump: + print ('check-static-inits.py: \'ldd\' not found; skipping test') + sys.exit (77) + +if sys.version_info < (3, 5): + print ('check-static-inits.py: needs python 3.5 for recursive support in glob') + sys.exit (77) + +OBJS = glob.glob (os.path.join (builddir, libs, '**', '*hb*.o'), recursive=True) +if not OBJS: + print ('check-static-inits.py: object files not found; skipping test') + sys.exit (77) + +stat = 0 +tested = 0 + +for obj in OBJS: + result = subprocess.run(objdump.split () + ['-t', obj], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + if result.returncode: + if result.stderr.find (b'not recognized') != -1: + # https://github.com/harfbuzz/harfbuzz/issues/3019 + print(('objdump %s returned "not recognized", skipping' % obj)) + continue + print(('objdump %s returned error:\n%s' % (obj, result.stderr.decode ('utf-8')))) + stat = 2 + + result = result.stdout.decode ('utf-8') + + # Checking that no object file has static initializers + for l in re.findall (r'^.*\.[cd]tors.*$', result, re.MULTILINE): + if not re.match (r'.*\b0+\b', l): + print(('Ouch, %s has static initializers/finalizers' % obj)) + stat = 1 + + # Checking that no object file has lazy static C++ constructors/destructors or other such stuff + if ('__cxa_' in result) and ('__ubsan_handle' not in result): + print(('Ouch, %s has lazy static C++ constructors/destructors or other such stuff' % obj)) + stat = 1 + + tested += 1 + +sys.exit (stat if tested else 77) diff --git a/gfx/harfbuzz/src/check-symbols.py b/gfx/harfbuzz/src/check-symbols.py index 2a9d58592a..0424584cea 100644 --- a/gfx/harfbuzz/src/check-symbols.py +++ b/gfx/harfbuzz/src/check-symbols.py @@ -1,74 +1,75 @@ -#!/usr/bin/env python3 - -import sys, os, shutil, subprocess, re, difflib - -os.environ['LC_ALL'] = 'C' # otherwise 'nm' prints in wrong order - -builddir = os.getenv ('builddir', os.path.dirname (__file__)) -libs = os.getenv ('libs', '.libs') - -IGNORED_SYMBOLS = '|'.join(['_fini', '_init', '_fdata', '_ftext', '_fbss', - '__bss_start', '__bss_start__', '__bss_end__', '_edata', '_end', '_bss_end__', - '__end__', '__gcov_.*', 'llvm_.*', 'flush_fn_list', 'writeout_fn_list', 'mangle_path', - 'lprofDirMode', 'reset_fn_list']) - -nm = os.getenv ('NM', shutil.which ('nm')) -if not nm: - print ('check-symbols.py: \'nm\' not found; skipping test') - sys.exit (77) - -cxxfilt = shutil.which ('c++filt') - -tested = False -stat = 0 - -for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject', 'harfbuzz-cairo']: - for suffix in ['so', 'dylib']: - so = os.path.join (builddir, libs, 'lib%s.%s' % (soname, suffix)) - if not os.path.exists (so): continue - - # On macOS, C symbols are prefixed with _ - symprefix = '_' if suffix == 'dylib' else '' - - EXPORTED_SYMBOLS = [s.split ()[2] - for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE) - if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)] - - # run again c++filt also if is available - if cxxfilt: - EXPORTED_SYMBOLS = subprocess.check_output ( - [cxxfilt], input='\n'.join (EXPORTED_SYMBOLS).encode () - ).decode ('utf-8').splitlines () - - prefix = (symprefix + os.path.basename (so)).replace ('libharfbuzz', 'hb').replace ('-', '_').split ('.')[0] - - print ('Checking that %s does not expose internal symbols' % so) - suspicious_symbols = [x for x in EXPORTED_SYMBOLS if not re.match (r'^%s(_|$)' % prefix, x)] - if suspicious_symbols: - print ('Ouch, internal symbols exposed:', suspicious_symbols) - stat = 1 - - def_path = os.path.join (builddir, soname + '.def') - if not os.path.exists (def_path): - print ('\'%s\' not found; skipping' % def_path) - else: - print ('Checking that %s has the same symbol list as %s' % (so, def_path)) - with open (def_path, 'r', encoding='utf-8') as f: def_file = f.read () - diff_result = list (difflib.context_diff ( - def_file.splitlines (), - ['EXPORTS'] + [re.sub ('^%shb' % symprefix, 'hb', x) for x in EXPORTED_SYMBOLS] + - # cheat: copy the last line from the def file! - [def_file.splitlines ()[-1]] - )) - - if diff_result: - print ('\n'.join (diff_result)) - stat = 1 - - tested = True - -if not tested: - print ('check-symbols.py: no shared libraries found; skipping test') - sys.exit (77) - -sys.exit (stat) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys, os, shutil, subprocess, re, difflib + +os.environ['LC_ALL'] = 'C' # otherwise 'nm' prints in wrong order + +builddir = os.getenv ('builddir', os.path.dirname (__file__)) +libs = os.getenv ('libs', '.libs') + +IGNORED_SYMBOLS = '|'.join(['_fini', '_init', '_fdata', '_ftext', '_fbss', + '__bss_start', '__bss_start__', '__bss_end__', '_edata', '_end', '_bss_end__', + '__end__', '__gcov_.*', 'llvm_.*', 'flush_fn_list', 'writeout_fn_list', 'mangle_path', + 'lprofDirMode', 'reset_fn_list']) + +nm = os.getenv ('NM', shutil.which ('nm')) +if not nm: + print ('check-symbols.py: \'nm\' not found; skipping test') + sys.exit (77) + +cxxfilt = shutil.which ('c++filt') + +tested = False +stat = 0 + +for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject', 'harfbuzz-cairo']: + for suffix in ['so', 'dylib']: + so = os.path.join (builddir, libs, 'lib%s.%s' % (soname, suffix)) + if not os.path.exists (so): continue + + # On macOS, C symbols are prefixed with _ + symprefix = '_' if suffix == 'dylib' else '' + + EXPORTED_SYMBOLS = [s.split ()[2] + for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE) + if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)] + + # run again c++filt also if is available + if cxxfilt: + EXPORTED_SYMBOLS = subprocess.check_output ( + [cxxfilt], input='\n'.join (EXPORTED_SYMBOLS).encode () + ).decode ('utf-8').splitlines () + + prefix = (symprefix + os.path.basename (so)).replace ('libharfbuzz', 'hb').replace ('-', '_').split ('.')[0] + + print(('Checking that %s does not expose internal symbols' % so)) + suspicious_symbols = [x for x in EXPORTED_SYMBOLS if not re.match (r'^%s(_|$)' % prefix, x)] + if suspicious_symbols: + print(('Ouch, internal symbols exposed:', suspicious_symbols)) + stat = 1 + + def_path = os.path.join (builddir, soname + '.def') + if not os.path.exists (def_path): + print(('\'%s\' not found; skipping' % def_path)) + else: + print(('Checking that %s has the same symbol list as %s' % (so, def_path))) + with open (def_path, 'r', encoding='utf-8') as f: def_file = f.read () + diff_result = list (difflib.context_diff ( + def_file.splitlines (), + ['EXPORTS'] + [re.sub ('^%shb' % symprefix, 'hb', x) for x in EXPORTED_SYMBOLS] + + # cheat: copy the last line from the def file! + [def_file.splitlines ()[-1]] + )) + + if diff_result: + print(('\n'.join (diff_result))) + stat = 1 + + tested = True + +if not tested: + print ('check-symbols.py: no shared libraries found; skipping test') + sys.exit (77) + +sys.exit (stat) diff --git a/gfx/harfbuzz/src/fix_get_types.py b/gfx/harfbuzz/src/fix_get_types.py index 8e7a08cfda..208b9dfcd6 100644 --- a/gfx/harfbuzz/src/fix_get_types.py +++ b/gfx/harfbuzz/src/fix_get_types.py @@ -1,15 +1,15 @@ -#!/usr/bin/env python3 - -import re -import argparse - -parser = argparse.ArgumentParser () -parser.add_argument ('input') -parser.add_argument ('output') -args = parser.parse_args () - -with open (args.input, 'r') as inp, open (args.output, 'w') as out: - for l in inp.readlines (): - l = re.sub ('_t_get_type', '_get_type', l) - l = re.sub ('_T \(', ' (', l) - out.write (l) +#!/usr/bin/env python3 + +import re +import argparse + +parser = argparse.ArgumentParser () +parser.add_argument ('input') +parser.add_argument ('output') +args = parser.parse_args () + +with open (args.input, 'r') as inp, open (args.output, 'w') as out: + for l in inp.readlines (): + l = re.sub ('_t_get_type', '_get_type', l) + l = re.sub ('_T \(', ' (', l) + out.write (l) diff --git a/gfx/harfbuzz/src/gen-arabic-joining-list.py b/gfx/harfbuzz/src/gen-arabic-joining-list.py index 6894b84ed9..e40be70cdc 100644 --- a/gfx/harfbuzz/src/gen-arabic-joining-list.py +++ b/gfx/harfbuzz/src/gen-arabic-joining-list.py @@ -1,106 +1,107 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-arabic-joining-table.py ArabicShaping.txt Scripts.txt - -Input files: -* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt -* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt -""" - -import os.path, sys - -if len (sys.argv) != 3: - sys.exit (__doc__) - -files = [open (x, encoding='utf-8') for x in sys.argv[1:]] - -headers = [[f.readline (), f.readline ()] for f in files] -while files[0].readline ().find ('##################') < 0: - pass - -def read (f): - mapping = {} - for line in f: - - j = line.find ('#') - if j >= 0: - line = line[:j] - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - - t = fields[1] - - for u in range (start, end + 1): - mapping[u] = t - - return mapping - -def read_joining_uu (f): - values = set () - for line in f: - - if line[0] == '#': - continue - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - if fields[2] in {'T', 'U'}: - continue - - values.add (int (fields[0], 16)) - - return sorted (values) - -def print_has_arabic_joining (scripts, joining_uu): - - print ("static bool") - print ("has_arabic_joining (hb_script_t script)") - print ("{") - print (" /* List of scripts that have data in arabic-table. */") - print (" switch ((int) script)") - print (" {") - - for script in sorted ({scripts[u] for u in joining_uu if scripts[u] not in {'Common', 'Inherited'}}): - print (" case HB_SCRIPT_{}:".format (script.upper ())) - - print (" return true;") - print () - print (" default:") - print (" return false;") - print (" }") - print ("}") - print () - -print ("/* == Start of generated function == */") -print ("/*") -print (" * The following function is generated by running:") -print (" *") -print (" * ./gen-arabic-joining-list.py ArabicShaping.txt Scripts.txt") -print (" *") -print (" * on files with these headers:") -print (" *") -for h in headers: - for l in h: - print (" * %s" % (l.strip ())) -print (" */") -print () -print ("#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") -print ("#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") -print () - -print_has_arabic_joining (read (files[1]), read_joining_uu (files[0])) - -print () -print ("#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */") -print () -print ("/* == End of generated function == */") +#!/usr/bin/env python3 + +"""usage: ./gen-arabic-joining-table.py ArabicShaping.txt Scripts.txt + +Input files: +* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt +* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt +""" + +from __future__ import print_function +import os.path, sys + +if len (sys.argv) != 3: + sys.exit (__doc__) + +files = [open (x, encoding='utf-8') for x in sys.argv[1:]] + +headers = [[f.readline (), f.readline ()] for f in files] +while files[0].readline ().find ('##################') < 0: + pass + +def read (f): + mapping = {} + for line in f: + + j = line.find ('#') + if j >= 0: + line = line[:j] + + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + + uu = fields[0].split ('..') + start = int (uu[0], 16) + if len (uu) == 1: + end = start + else: + end = int (uu[1], 16) + + t = fields[1] + + for u in range (start, end + 1): + mapping[u] = t + + return mapping + +def read_joining_uu (f): + values = set () + for line in f: + + if line[0] == '#': + continue + + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + if fields[2] in {'T', 'U'}: + continue + + values.add (int (fields[0], 16)) + + return sorted (values) + +def print_has_arabic_joining (scripts, joining_uu): + + print ("static bool") + print ("has_arabic_joining (hb_script_t script)") + print ("{") + print (" /* List of scripts that have data in arabic-table. */") + print (" switch ((int) script)") + print (" {") + + for script in sorted ({scripts[u] for u in joining_uu if scripts[u] not in {'Common', 'Inherited'}}): + print((" case HB_SCRIPT_{}:".format (script.upper ()))) + + print (" return true;") + print () + print (" default:") + print (" return false;") + print (" }") + print ("}") + print () + +print ("/* == Start of generated function == */") +print ("/*") +print (" * The following function is generated by running:") +print (" *") +print (" * ./gen-arabic-joining-list.py ArabicShaping.txt Scripts.txt") +print (" *") +print (" * on files with these headers:") +print (" *") +for h in headers: + for l in h: + print((" * %s" % (l.strip ()))) +print (" */") +print () +print ("#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") +print ("#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") +print () + +print_has_arabic_joining (read (files[1]), read_joining_uu (files[0])) + +print () +print ("#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */") +print () +print ("/* == End of generated function == */") diff --git a/gfx/harfbuzz/src/gen-arabic-pua.py b/gfx/harfbuzz/src/gen-arabic-pua.py index 662aa44572..15c2ab7b46 100644 --- a/gfx/harfbuzz/src/gen-arabic-pua.py +++ b/gfx/harfbuzz/src/gen-arabic-pua.py @@ -1,35 +1,36 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-arabic-pua.py -""" - -import packTab - - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following table is generated by running:") -print (" *") -print (" * ./gen-arabic-pua.py") -print (" *") -print (" */") -print () -print ("#ifndef HB_OT_SHAPER_ARABIC_PUA_HH") -print ("#define HB_OT_SHAPER_ARABIC_PUA_HH") -print () - -code = packTab.Code('_hb_arabic') - -for p in ("ArabicPUASimplified.txt", "ArabicPUATraditional.txt"): - with open (p, encoding='utf-8') as f: - fields = [l.split('\t') for l in f if l[:1] != '#'] - data = {int(fs[1], 16):int(fs[0], 16) for fs in fields} - sol = packTab.pack_table(data, compression=9) - sol.genCode(code, f'pua_{p[9:13].lower()}_map') - -code.print_c(linkage='static inline') - -print () -print ("#endif /* HB_OT_SHAPER_ARABIC_PUA_HH */") -print () -print ("/* == End of generated table == */") +#!/usr/bin/env python3 + +"""usage: ./gen-arabic-pua.py +""" + +from __future__ import print_function +import packTab + + +print ("/* == Start of generated table == */") +print ("/*") +print (" * The following table is generated by running:") +print (" *") +print (" * ./gen-arabic-pua.py") +print (" *") +print (" */") +print () +print ("#ifndef HB_OT_SHAPER_ARABIC_PUA_HH") +print ("#define HB_OT_SHAPER_ARABIC_PUA_HH") +print () + +code = packTab.Code('_hb_arabic') + +for p in ("ArabicPUASimplified.txt", "ArabicPUATraditional.txt"): + with open (p, encoding='utf-8') as f: + fields = [l.split('\t') for l in f if l[:1] != '#'] + data = {int(fs[1], 16):int(fs[0], 16) for fs in fields} + sol = packTab.pack_table(data, compression=9) + sol.genCode(code, f'pua_{p[9:13].lower()}_map') + +code.print_c(linkage='static inline') + +print () +print ("#endif /* HB_OT_SHAPER_ARABIC_PUA_HH */") +print () +print ("/* == End of generated table == */") diff --git a/gfx/harfbuzz/src/gen-def.py b/gfx/harfbuzz/src/gen-def.py index 946a78efca..6011817bc5 100644 --- a/gfx/harfbuzz/src/gen-def.py +++ b/gfx/harfbuzz/src/gen-def.py @@ -1,33 +1,33 @@ -#!/usr/bin/env python3 - -"usage: gen-def.py harfbuzz.def hb.h [hb-blob.h hb-buffer.h ...]" - -import os, re, sys - -if len (sys.argv) < 3: - sys.exit(__doc__) - -output_file = sys.argv[1] -header_paths = sys.argv[2:] - -headers_content = [] -for h in header_paths: - if h.endswith (".h"): - with open (h, encoding='utf-8') as f: headers_content.append (f.read ()) - -symbols = sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M)) -if '--experimental-api' not in sys.argv: - # Move these to harfbuzz-sections.txt when got stable - experimental_symbols = \ -"""hb_shape_justify -hb_subset_repack_or_fail -hb_subset_input_override_name_table -""".splitlines () - symbols = [x for x in symbols if x not in experimental_symbols] -symbols = "\n".join (symbols) - -result = symbols if os.getenv ('PLAIN_LIST', '') else """EXPORTS -%s -LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('src/', '').replace ('.def', '')) - -with open (output_file, "w") as f: f.write (result) +#!/usr/bin/env python3 + +"usage: gen-def.py harfbuzz.def hb.h [hb-blob.h hb-buffer.h ...]" + +import os, re, sys + +if len (sys.argv) < 3: + sys.exit(__doc__) + +output_file = sys.argv[1] +header_paths = sys.argv[2:] + +headers_content = [] +for h in header_paths: + if h.endswith (".h"): + with open (h, encoding='utf-8') as f: headers_content.append (f.read ()) + +symbols = sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M)) +if '--experimental-api' not in sys.argv: + # Move these to harfbuzz-sections.txt when got stable + experimental_symbols = \ +"""hb_shape_justify +hb_subset_repack_or_fail +hb_subset_input_override_name_table +""".splitlines () + symbols = [x for x in symbols if x not in experimental_symbols] +symbols = "\n".join (symbols) + +result = symbols if os.getenv ('PLAIN_LIST', '') else """EXPORTS +%s +LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('src/', '').replace ('.def', '')) + +with open (output_file, "w") as f: f.write (result) diff --git a/gfx/harfbuzz/src/gen-emoji-table.py b/gfx/harfbuzz/src/gen-emoji-table.py index 3ab3279ab3..ccb3a546ef 100644 --- a/gfx/harfbuzz/src/gen-emoji-table.py +++ b/gfx/harfbuzz/src/gen-emoji-table.py @@ -1,98 +1,99 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-emoji-table.py emoji-data.txt emoji-test.txt - -Input file: -* https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt -* https://www.unicode.org/Public/emoji/latest/emoji-test.txt -""" - -import sys -from collections import OrderedDict -import packTab - -if len (sys.argv) != 3: - sys.exit (__doc__) - -f = open(sys.argv[1]) -header = [f.readline () for _ in range(10)] - -ranges = OrderedDict() -for line in f.readlines(): - line = line.strip() - if not line or line[0] == '#': - continue - rang, typ = [s.strip() for s in line.split('#')[0].split(';')[:2]] - - rang = [int(s, 16) for s in rang.split('..')] - if len(rang) > 1: - start, end = rang - else: - start = end = rang[0] - - if typ not in ranges: - ranges[typ] = [] - if ranges[typ] and ranges[typ][-1][1] == start - 1: - ranges[typ][-1] = (ranges[typ][-1][0], end) - else: - ranges[typ].append((start, end)) - - - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following tables are generated by running:") -print (" *") -print (" * ./gen-emoji-table.py emoji-data.txt") -print (" *") -print (" * on file with this header:") -print (" *") -for l in header: - print (" * %s" % (l.strip())) -print (" */") -print () -print ("#ifndef HB_UNICODE_EMOJI_TABLE_HH") -print ("#define HB_UNICODE_EMOJI_TABLE_HH") -print () -print ('#include "hb-unicode.hh"') -print () - -for typ, s in ranges.items(): - if typ != "Extended_Pictographic": continue - - arr = dict() - for start,end in s: - for i in range(start, end + 1): - arr[i] = 1 - - sol = packTab.pack_table(arr, 0, compression=9) - code = packTab.Code('_hb_emoji') - sol.genCode(code, 'is_'+typ) - code.print_c(linkage='static inline') - print() - -print () -print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */") -print () -print ("/* == End of generated table == */") - - -# Generate test file. -sequences = [] -with open(sys.argv[2]) as f: - for line in f.readlines(): - if "#" in line: - line = line[:line.index("#")] - if ";" in line: - line = line[:line.index(";")] - line = line.strip() - line = line.split(" ") - if len(line) < 2: - continue - sequences.append(line) - -with open("../test/shape/data/in-house/tests/emoji-clusters.tests", "w") as f: - for sequence in sequences: - f.write("../fonts/AdobeBlank2.ttf;--no-glyph-names --no-positions --font-funcs=ot") - f.write(";" + ",".join(sequence)) - f.write(";[" + "|".join("1=0" for c in sequence) + "]\n") +#!/usr/bin/env python3 + +"""usage: ./gen-emoji-table.py emoji-data.txt emoji-test.txt + +Input file: +* https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt +* https://www.unicode.org/Public/emoji/latest/emoji-test.txt +""" + +from __future__ import print_function +import sys +from collections import OrderedDict +import packTab + +if len (sys.argv) != 3: + sys.exit (__doc__) + +f = open(sys.argv[1]) +header = [f.readline () for _ in range(10)] + +ranges = OrderedDict() +for line in f.readlines(): + line = line.strip() + if not line or line[0] == '#': + continue + rang, typ = [s.strip() for s in line.split('#')[0].split(';')[:2]] + + rang = [int(s, 16) for s in rang.split('..')] + if len(rang) > 1: + start, end = rang + else: + start = end = rang[0] + + if typ not in ranges: + ranges[typ] = [] + if ranges[typ] and ranges[typ][-1][1] == start - 1: + ranges[typ][-1] = (ranges[typ][-1][0], end) + else: + ranges[typ].append((start, end)) + + + +print ("/* == Start of generated table == */") +print ("/*") +print (" * The following tables are generated by running:") +print (" *") +print (" * ./gen-emoji-table.py emoji-data.txt") +print (" *") +print (" * on file with this header:") +print (" *") +for l in header: + print((" * %s" % (l.strip()))) +print (" */") +print () +print ("#ifndef HB_UNICODE_EMOJI_TABLE_HH") +print ("#define HB_UNICODE_EMOJI_TABLE_HH") +print () +print ('#include "hb-unicode.hh"') +print () + +for typ, s in ranges.items(): + if typ != "Extended_Pictographic": continue + + arr = dict() + for start,end in s: + for i in range(start, end + 1): + arr[i] = 1 + + sol = packTab.pack_table(arr, 0, compression=9) + code = packTab.Code('_hb_emoji') + sol.genCode(code, 'is_'+typ) + code.print_c(linkage='static inline') + print() + +print () +print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */") +print () +print ("/* == End of generated table == */") + + +# Generate test file. +sequences = [] +with open(sys.argv[2]) as f: + for line in f.readlines(): + if "#" in line: + line = line[:line.index("#")] + if ";" in line: + line = line[:line.index(";")] + line = line.strip() + line = line.split(" ") + if len(line) < 2: + continue + sequences.append(line) + +with open("../test/shape/data/in-house/tests/emoji-clusters.tests", "w") as f: + for sequence in sequences: + f.write("../fonts/AdobeBlank2.ttf;--no-glyph-names --no-positions --font-funcs=ot") + f.write(";" + ",".join(sequence)) + f.write(";[" + "|".join("1=0" for c in sequence) + "]\n") diff --git a/gfx/harfbuzz/src/gen-harfbuzzcc.py b/gfx/harfbuzz/src/gen-harfbuzzcc.py index 4e409b2791..227384043e 100644 --- a/gfx/harfbuzz/src/gen-harfbuzzcc.py +++ b/gfx/harfbuzz/src/gen-harfbuzzcc.py @@ -1,24 +1,24 @@ -#!/usr/bin/env python3 - -"This tool is intended to be used from meson" - -import os, sys, shutil - -if len (sys.argv) < 3: - sys.exit (__doc__) - -OUTPUT = sys.argv[1] -CURRENT_SOURCE_DIR = sys.argv[2] - -# make sure input files are unique -sources = sorted(set(sys.argv[3:])) - -with open (OUTPUT, "wb") as f: - f.write ("".join ('#include "{}"\n'.format (os.path.relpath (os.path.abspath (x), CURRENT_SOURCE_DIR)) for x in sources if x.endswith (".cc")).encode ()) - -# copy it also to the source tree, but only if it has changed -baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)) -with open(baseline_filename, "rb") as baseline: - with open(OUTPUT, "rb") as generated: - if baseline.read() != generated.read(): - shutil.copyfile (OUTPUT, baseline_filename) +#!/usr/bin/env python3 + +"This tool is intended to be used from meson" + +import os, sys, shutil + +if len (sys.argv) < 3: + sys.exit (__doc__) + +OUTPUT = sys.argv[1] +CURRENT_SOURCE_DIR = sys.argv[2] + +# make sure input files are unique +sources = sorted(set(sys.argv[3:])) + +with open (OUTPUT, "wb") as f: + f.write ("".join ('#include "{}"\n'.format (os.path.relpath (os.path.abspath (x), CURRENT_SOURCE_DIR)) for x in sources if x.endswith (".cc")).encode ()) + +# copy it also to the source tree, but only if it has changed +baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)) +with open(baseline_filename, "rb") as baseline: + with open(OUTPUT, "rb") as generated: + if baseline.read() != generated.read(): + shutil.copyfile (OUTPUT, baseline_filename) diff --git a/gfx/harfbuzz/src/gen-hb-version.py b/gfx/harfbuzz/src/gen-hb-version.py index 9503ad1c1c..06018edfcf 100644 --- a/gfx/harfbuzz/src/gen-hb-version.py +++ b/gfx/harfbuzz/src/gen-hb-version.py @@ -1,40 +1,40 @@ -#!/usr/bin/env python3 - -"This tool is intended to be used from meson" - -import os, sys, shutil, re - -if len (sys.argv) < 4: - sys.exit(__doc__) - -version = sys.argv[1] -major, minor, micro = version.split (".") - -OUTPUT = sys.argv[2] -INPUT = sys.argv[3] -CURRENT_SOURCE_DIR = os.path.dirname(INPUT) - -try: - with open (OUTPUT, "r", encoding='utf-8') as old_output: - for line in old_output: - old_version = re.match (r"#define HB_VERSION_STRING \"(\d.\d.\d)\"", line) - if old_version and old_version[1] == version: - sys.exit () -except IOError: - pass - -with open (INPUT, "r", encoding='utf-8') as template: - with open (OUTPUT, "wb") as output: - output.write (template.read () - .replace ("@HB_VERSION_MAJOR@", major) - .replace ("@HB_VERSION_MINOR@", minor) - .replace ("@HB_VERSION_MICRO@", micro) - .replace ("@HB_VERSION@", version) - .encode ()) - -# copy it also to the source tree, but only if it has changed -baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)) -with open(baseline_filename, "rb") as baseline: - with open(OUTPUT, "rb") as generated: - if baseline.read() != generated.read(): - shutil.copyfile (OUTPUT, baseline_filename) +#!/usr/bin/env python3 + +"This tool is intended to be used from meson" + +import os, sys, shutil, re + +if len (sys.argv) < 4: + sys.exit(__doc__) + +version = sys.argv[1] +major, minor, micro = version.split (".") + +OUTPUT = sys.argv[2] +INPUT = sys.argv[3] +CURRENT_SOURCE_DIR = os.path.dirname(INPUT) + +try: + with open (OUTPUT, "r", encoding='utf-8') as old_output: + for line in old_output: + old_version = re.match (r"#define HB_VERSION_STRING \"(\d.\d.\d)\"", line) + if old_version and old_version[1] == version: + sys.exit () +except IOError: + pass + +with open (INPUT, "r", encoding='utf-8') as template: + with open (OUTPUT, "wb") as output: + output.write (template.read () + .replace ("@HB_VERSION_MAJOR@", major) + .replace ("@HB_VERSION_MINOR@", minor) + .replace ("@HB_VERSION_MICRO@", micro) + .replace ("@HB_VERSION@", version) + .encode ()) + +# copy it also to the source tree, but only if it has changed +baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)) +with open(baseline_filename, "rb") as baseline: + with open(OUTPUT, "rb") as generated: + if baseline.read() != generated.read(): + shutil.copyfile (OUTPUT, baseline_filename) diff --git a/gfx/harfbuzz/src/gen-os2-unicode-ranges.py b/gfx/harfbuzz/src/gen-os2-unicode-ranges.py index b8b6489dfc..d7e5f27203 100644 --- a/gfx/harfbuzz/src/gen-os2-unicode-ranges.py +++ b/gfx/harfbuzz/src/gen-os2-unicode-ranges.py @@ -1,50 +1,51 @@ -#!/usr/bin/env python3 - -"""Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh -Input is a tab separated list of unicode ranges from the otspec -(https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur). -""" - -import re -import sys - - -print ("""static OS2Range _hb_os2_unicode_ranges[] = -{""") - -args = sys.argv[1:] -input_file = args[0] - -with open (input_file, mode="r", encoding="utf-8") as f: - - all_ranges = [] - current_bit = 0 - while True: - line = f.readline().strip() - if not line: - break - fields = re.split(r'\t+', line) - if len(fields) == 3: - current_bit = fields[0] - fields = fields[1:] - elif len(fields) > 3: - raise Exception("bad input :(.") - - name = fields[0] - ranges = re.split("-", fields[1]) - if len(ranges) != 2: - raise Exception("bad input :(.") - - v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name)) - all_ranges.append(v) - -all_ranges = sorted(all_ranges, key=lambda t: t[0]) - -for ranges in all_ranges: - start = ("0x%X" % ranges[0]).rjust(8) - end = ("0x%X" % ranges[1]).rjust(8) - bit = ("%s" % ranges[2]).rjust(3) - - print (" {%s, %s, %s}, // %s" % (start, end, bit, ranges[3])) - -print ("""};""") +#!/usr/bin/env python3 + +"""Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh +Input is a tab separated list of unicode ranges from the otspec +(https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur). +""" + +from __future__ import print_function +import re +import sys + + +print ("""static OS2Range _hb_os2_unicode_ranges[] = +{""") + +args = sys.argv[1:] +input_file = args[0] + +with open (input_file, mode="r", encoding="utf-8") as f: + + all_ranges = [] + current_bit = 0 + while True: + line = f.readline().strip() + if not line: + break + fields = re.split(r'\t+', line) + if len(fields) == 3: + current_bit = fields[0] + fields = fields[1:] + elif len(fields) > 3: + raise Exception("bad input :(.") + + name = fields[0] + ranges = re.split("-", fields[1]) + if len(ranges) != 2: + raise Exception("bad input :(.") + + v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name)) + all_ranges.append(v) + +all_ranges = sorted(all_ranges, key=lambda t: t[0]) + +for ranges in all_ranges: + start = ("0x%X" % ranges[0]).rjust(8) + end = ("0x%X" % ranges[1]).rjust(8) + bit = ("%s" % ranges[2]).rjust(3) + + print((" {%s, %s, %s}, // %s" % (start, end, bit, ranges[3]))) + +print ("""};""") diff --git a/gfx/harfbuzz/src/gen-ragel-artifacts.py b/gfx/harfbuzz/src/gen-ragel-artifacts.py index fa235f0e9a..8bbb375bfb 100644 --- a/gfx/harfbuzz/src/gen-ragel-artifacts.py +++ b/gfx/harfbuzz/src/gen-ragel-artifacts.py @@ -1,25 +1,25 @@ -#!/usr/bin/env python3 - -"This tool is intended to be used from meson" - -import os, os.path, sys, subprocess, shutil - -ragel = sys.argv[1] -if not ragel: - sys.exit ('You have to install ragel if you are going to develop HarfBuzz itself') - -if len (sys.argv) < 4: - sys.exit (__doc__) - -OUTPUT = sys.argv[2] -CURRENT_SOURCE_DIR = sys.argv[3] -INPUT = sys.argv[4] - -outdir = os.path.dirname (OUTPUT) -shutil.copy (INPUT, outdir) -rl = os.path.basename (INPUT) -hh = rl.replace ('.rl', '.hh') -subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait () - -# copy it also to src/ -shutil.copyfile (os.path.join (outdir, hh), os.path.join (CURRENT_SOURCE_DIR, hh)) +#!/usr/bin/env python3 + +"This tool is intended to be used from meson" + +import os, os.path, sys, subprocess, shutil + +ragel = sys.argv[1] +if not ragel: + sys.exit ('You have to install ragel if you are going to develop HarfBuzz itself') + +if len (sys.argv) < 4: + sys.exit (__doc__) + +OUTPUT = sys.argv[2] +CURRENT_SOURCE_DIR = sys.argv[3] +INPUT = sys.argv[4] + +outdir = os.path.dirname (OUTPUT) +shutil.copy (INPUT, outdir) +rl = os.path.basename (INPUT) +hh = rl.replace ('.rl', '.hh') +subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait () + +# copy it also to src/ +shutil.copyfile (os.path.join (outdir, hh), os.path.join (CURRENT_SOURCE_DIR, hh)) diff --git a/gfx/harfbuzz/src/gen-tag-table.py b/gfx/harfbuzz/src/gen-tag-table.py index 54817a6ed0..35819800d3 100644 --- a/gfx/harfbuzz/src/gen-tag-table.py +++ b/gfx/harfbuzz/src/gen-tag-table.py @@ -1,1216 +1,1216 @@ -#!/usr/bin/env python3 - -"""Generator of the mapping from OpenType tags to BCP 47 tags and vice -versa. - -It creates a ``const LangTag[]``, matching the tags from the OpenType -languages system tag list to the language subtags of the BCP 47 language -subtag registry, with some manual adjustments. The mappings are -supplemented with macrolanguages' sublanguages and retired codes' -replacements, according to BCP 47 and some manual additions where BCP 47 -omits a retired code entirely. - -Also generated is a function, ``hb_ot_ambiguous_tag_to_language``, -intended for use by ``hb_ot_tag_to_language``. It maps OpenType tags -back to BCP 47 tags. Ambiguous OpenType tags (those that correspond to -multiple BCP 47 tags) are listed here, except when the alphabetically -first BCP 47 tag happens to be the chosen disambiguated tag. In that -case, the fallback behavior will choose the right tag anyway. - -usage: ./gen-tag-table.py languagetags language-subtag-registry - -Input files: -* https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags -* https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry -""" - -import collections -import html -from html.parser import HTMLParser -import itertools -import re -import sys -import unicodedata - -if len (sys.argv) != 3: - sys.exit (__doc__) - -def expect (condition, message=None): - if not condition: - if message is None: - raise AssertionError - raise AssertionError (message) - -def write (s): - sys.stdout.flush () - sys.stdout.buffer.write (s.encode ('utf-8')) - -DEFAULT_LANGUAGE_SYSTEM = '' - -# from https://www-01.sil.org/iso639-3/iso-639-3.tab -ISO_639_3_TO_1 = { - 'aar': 'aa', - 'abk': 'ab', - 'afr': 'af', - 'aka': 'ak', - 'amh': 'am', - 'ara': 'ar', - 'arg': 'an', - 'asm': 'as', - 'ava': 'av', - 'ave': 'ae', - 'aym': 'ay', - 'aze': 'az', - 'bak': 'ba', - 'bam': 'bm', - 'bel': 'be', - 'ben': 'bn', - 'bis': 'bi', - 'bod': 'bo', - 'bos': 'bs', - 'bre': 'br', - 'bul': 'bg', - 'cat': 'ca', - 'ces': 'cs', - 'cha': 'ch', - 'che': 'ce', - 'chu': 'cu', - 'chv': 'cv', - 'cor': 'kw', - 'cos': 'co', - 'cre': 'cr', - 'cym': 'cy', - 'dan': 'da', - 'deu': 'de', - 'div': 'dv', - 'dzo': 'dz', - 'ell': 'el', - 'eng': 'en', - 'epo': 'eo', - 'est': 'et', - 'eus': 'eu', - 'ewe': 'ee', - 'fao': 'fo', - 'fas': 'fa', - 'fij': 'fj', - 'fin': 'fi', - 'fra': 'fr', - 'fry': 'fy', - 'ful': 'ff', - 'gla': 'gd', - 'gle': 'ga', - 'glg': 'gl', - 'glv': 'gv', - 'grn': 'gn', - 'guj': 'gu', - 'hat': 'ht', - 'hau': 'ha', - 'hbs': 'sh', - 'heb': 'he', - 'her': 'hz', - 'hin': 'hi', - 'hmo': 'ho', - 'hrv': 'hr', - 'hun': 'hu', - 'hye': 'hy', - 'ibo': 'ig', - 'ido': 'io', - 'iii': 'ii', - 'iku': 'iu', - 'ile': 'ie', - 'ina': 'ia', - 'ind': 'id', - 'ipk': 'ik', - 'isl': 'is', - 'ita': 'it', - 'jav': 'jv', - 'jpn': 'ja', - 'kal': 'kl', - 'kan': 'kn', - 'kas': 'ks', - 'kat': 'ka', - 'kau': 'kr', - 'kaz': 'kk', - 'khm': 'km', - 'kik': 'ki', - 'kin': 'rw', - 'kir': 'ky', - 'kom': 'kv', - 'kon': 'kg', - 'kor': 'ko', - 'kua': 'kj', - 'kur': 'ku', - 'lao': 'lo', - 'lat': 'la', - 'lav': 'lv', - 'lim': 'li', - 'lin': 'ln', - 'lit': 'lt', - 'ltz': 'lb', - 'lub': 'lu', - 'lug': 'lg', - 'mah': 'mh', - 'mal': 'ml', - 'mar': 'mr', - 'mkd': 'mk', - 'mlg': 'mg', - 'mlt': 'mt', - 'mol': 'mo', - 'mon': 'mn', - 'mri': 'mi', - 'msa': 'ms', - 'mya': 'my', - 'nau': 'na', - 'nav': 'nv', - 'nbl': 'nr', - 'nde': 'nd', - 'ndo': 'ng', - 'nep': 'ne', - 'nld': 'nl', - 'nno': 'nn', - 'nob': 'nb', - 'nor': 'no', - 'nya': 'ny', - 'oci': 'oc', - 'oji': 'oj', - 'ori': 'or', - 'orm': 'om', - 'oss': 'os', - 'pan': 'pa', - 'pli': 'pi', - 'pol': 'pl', - 'por': 'pt', - 'pus': 'ps', - 'que': 'qu', - 'roh': 'rm', - 'ron': 'ro', - 'run': 'rn', - 'rus': 'ru', - 'sag': 'sg', - 'san': 'sa', - 'sin': 'si', - 'slk': 'sk', - 'slv': 'sl', - 'sme': 'se', - 'smo': 'sm', - 'sna': 'sn', - 'snd': 'sd', - 'som': 'so', - 'sot': 'st', - 'spa': 'es', - 'sqi': 'sq', - 'srd': 'sc', - 'srp': 'sr', - 'ssw': 'ss', - 'sun': 'su', - 'swa': 'sw', - 'swe': 'sv', - 'tah': 'ty', - 'tam': 'ta', - 'tat': 'tt', - 'tel': 'te', - 'tgk': 'tg', - 'tgl': 'tl', - 'tha': 'th', - 'tir': 'ti', - 'ton': 'to', - 'tsn': 'tn', - 'tso': 'ts', - 'tuk': 'tk', - 'tur': 'tr', - 'twi': 'tw', - 'uig': 'ug', - 'ukr': 'uk', - 'urd': 'ur', - 'uzb': 'uz', - 'ven': 've', - 'vie': 'vi', - 'vol': 'vo', - 'wln': 'wa', - 'wol': 'wo', - 'xho': 'xh', - 'yid': 'yi', - 'yor': 'yo', - 'zha': 'za', - 'zho': 'zh', - 'zul': 'zu', -} - -class LanguageTag (object): - """A BCP 47 language tag. - - Attributes: - subtags (List[str]): The list of subtags in this tag. - grandfathered (bool): Whether this tag is grandfathered. If - ``true``, the entire lowercased tag is the ``language`` - and the other subtag fields are empty. - language (str): The language subtag. - script (str): The script subtag. - region (str): The region subtag. - variant (str): The variant subtag. - - Args: - tag (str): A BCP 47 language tag. - - """ - def __init__ (self, tag): - global bcp_47 - self.subtags = tag.lower ().split ('-') - self.grandfathered = tag.lower () in bcp_47.grandfathered - if self.grandfathered: - self.language = tag.lower () - self.script = '' - self.region = '' - self.variant = '' - else: - self.language = self.subtags[0] - self.script = self._find_first (lambda s: len (s) == 4 and s[0] > '9', self.subtags) - self.region = self._find_first (lambda s: len (s) == 2 and s[0] > '9' or len (s) == 3 and s[0] <= '9', self.subtags[1:]) - self.variant = self._find_first (lambda s: len (s) > 4 or len (s) == 4 and s[0] <= '9', self.subtags) - - def __str__(self): - return '-'.join(self.subtags) - - def __repr__ (self): - return 'LanguageTag(%r)' % str(self) - - @staticmethod - def _find_first (function, sequence): - try: - return next (iter (filter (function, sequence))) - except StopIteration: - return None - - def is_complex (self): - """Return whether this tag is too complex to represent as a - ``LangTag`` in the generated code. - - Complex tags need to be handled in - ``hb_ot_tags_from_complex_language``. - - Returns: - Whether this tag is complex. - """ - return not (len (self.subtags) == 1 - or self.grandfathered - and len (self.subtags[1]) != 3 - and ot.from_bcp_47[self.subtags[0]] == ot.from_bcp_47[self.language]) - - def get_group (self): - """Return the group into which this tag should be categorized in - ``hb_ot_tags_from_complex_language``. - - The group is the first letter of the tag, or ``'und'`` if this tag - should not be matched in a ``switch`` statement in the generated - code. - - Returns: - This tag's group. - """ - return ('und' - if (self.language == 'und' - or self.variant in bcp_47.prefixes and len (bcp_47.prefixes[self.variant]) == 1) - else self.language[0]) - -class OpenTypeRegistryParser (HTMLParser): - """A parser for the OpenType language system tag registry. - - Attributes: - header (str): The "last updated" line of the registry. - names (Mapping[str, str]): A map of language system tags to the - names they are given in the registry. - ranks (DefaultDict[str, int]): A map of language system tags to - numbers. If a single BCP 47 tag corresponds to multiple - OpenType tags, the tags are ordered in increasing order by - rank. The rank is based on the number of BCP 47 tags - associated with a tag, though it may be manually modified. - to_bcp_47 (DefaultDict[str, AbstractSet[str]]): A map of - OpenType language system tags to sets of BCP 47 tags. - from_bcp_47 (DefaultDict[str, AbstractSet[str]]): ``to_bcp_47`` - inverted. Its values start as unsorted sets; - ``sort_languages`` converts them to sorted lists. - from_bcp_47_uninherited (Optional[Dict[str, AbstractSet[str]]]): - A copy of ``from_bcp_47``. It starts as ``None`` and is - populated at the beginning of the first call to - ``inherit_from_macrolanguages``. - - """ - def __init__ (self): - HTMLParser.__init__ (self) - self.header = '' - self.names = {} - self.ranks = collections.defaultdict (int) - self.to_bcp_47 = collections.defaultdict (set) - self.from_bcp_47 = collections.defaultdict (set) - self.from_bcp_47_uninherited = None - # Whether the parser is in a element - self._td = False - # Whether the parser is after a
element within the current element - self._br = False - # The text of the elements of the current element. - self._current_tr = [] - - def handle_starttag (self, tag, attrs): - if tag == 'br': - self._br = True - elif tag == 'meta': - for attr, value in attrs: - if attr == 'name' and value == 'updated_at': - self.header = self.get_starttag_text () - break - elif tag == 'td': - self._td = True - self._current_tr.append ('') - elif tag == 'tr': - self._br = False - self._current_tr = [] - - def handle_endtag (self, tag): - if tag == 'td': - self._td = False - elif tag == 'tr' and self._current_tr: - expect (2 <= len (self._current_tr) <= 3) - name = self._current_tr[0].strip () - tag = self._current_tr[1].strip ("\t\n\v\f\r '") - rank = 0 - if len (tag) > 4: - expect (tag.endswith (' (deprecated)'), 'ill-formed OpenType tag: %s' % tag) - name += ' (deprecated)' - tag = tag.split (' ')[0] - rank = 1 - self.names[tag] = re.sub (' languages$', '', name) - if not self._current_tr[2]: - return - iso_codes = self._current_tr[2].strip () - self.to_bcp_47[tag].update (ISO_639_3_TO_1.get (code, code) for code in iso_codes.replace (' ', '').split (',')) - rank += 2 * len (self.to_bcp_47[tag]) - self.ranks[tag] = rank - - def handle_data (self, data): - if self._td and not self._br: - self._current_tr[-1] += data - - def handle_charref (self, name): - self.handle_data (html.unescape ('&#%s;' % name)) - - def handle_entityref (self, name): - self.handle_data (html.unescape ('&%s;' % name)) - - def parse (self, filename): - """Parse the OpenType language system tag registry. - - Args: - filename (str): The file name of the registry. - """ - with open (filename, encoding='utf-8') as f: - self.feed (f.read ()) - expect (self.header) - for tag, iso_codes in self.to_bcp_47.items (): - for iso_code in iso_codes: - self.from_bcp_47[iso_code].add (tag) - - def add_language (self, bcp_47_tag, ot_tag): - """Add a language as if it were in the registry. - - Args: - bcp_47_tag (str): A BCP 47 tag. If the tag is more than just - a language subtag, and if the language subtag is a - macrolanguage, then new languages are added corresponding - to the macrolanguages' individual languages with the - remainder of the tag appended. - ot_tag (str): An OpenType language system tag. - """ - global bcp_47 - self.to_bcp_47[ot_tag].add (bcp_47_tag) - self.from_bcp_47[bcp_47_tag].add (ot_tag) - if bcp_47_tag.lower () not in bcp_47.grandfathered: - try: - [macrolanguage, suffix] = bcp_47_tag.split ('-', 1) - if macrolanguage in bcp_47.macrolanguages: - s = set () - for language in bcp_47.macrolanguages[macrolanguage]: - if language.lower () not in bcp_47.grandfathered: - s.add ('%s-%s' % (language, suffix)) - bcp_47.macrolanguages['%s-%s' % (macrolanguage, suffix)] = s - except ValueError: - pass - - @staticmethod - def _remove_language (tag_1, dict_1, dict_2): - for tag_2 in dict_1.pop (tag_1): - dict_2[tag_2].remove (tag_1) - if not dict_2[tag_2]: - del dict_2[tag_2] - - def remove_language_ot (self, ot_tag): - """Remove an OpenType tag from the registry. - - Args: - ot_tag (str): An OpenType tag. - """ - self._remove_language (ot_tag, self.to_bcp_47, self.from_bcp_47) - - def remove_language_bcp_47 (self, bcp_47_tag): - """Remove a BCP 47 tag from the registry. - - Args: - bcp_47_tag (str): A BCP 47 tag. - """ - self._remove_language (bcp_47_tag, self.from_bcp_47, self.to_bcp_47) - - def inherit_from_macrolanguages (self): - """Copy mappings from macrolanguages to individual languages. - - If a BCP 47 tag for an individual mapping has no OpenType - mapping but its macrolanguage does, the mapping is copied to - the individual language. For example, als (Tosk Albanian) has no - explicit mapping, so it inherits from sq (Albanian) the mapping - to SQI. - - However, if an OpenType tag maps to a BCP 47 macrolanguage and - some but not all of its individual languages, the mapping is not - inherited from the macrolanguage to the missing individual - languages. For example, INUK (Nunavik Inuktitut) is mapped to - ike (Eastern Canadian Inuktitut) and iu (Inuktitut) but not to - ikt (Inuinnaqtun, which is an individual language of iu), so - this method does not add a mapping from ikt to INUK. - - If a BCP 47 tag for a macrolanguage has no OpenType mapping but - some of its individual languages do, their mappings are copied - to the macrolanguage. - """ - global bcp_47 - first_time = self.from_bcp_47_uninherited is None - if first_time: - self.from_bcp_47_uninherited = dict (self.from_bcp_47) - for macrolanguage, languages in dict (bcp_47.macrolanguages).items (): - ot_macrolanguages = { - ot_macrolanguage for ot_macrolanguage in self.from_bcp_47_uninherited.get (macrolanguage, set ()) - } - blocked_ot_macrolanguages = set () - if 'retired code' not in bcp_47.scopes.get (macrolanguage, ''): - for ot_macrolanguage in ot_macrolanguages: - round_trip_macrolanguages = { - l for l in self.to_bcp_47[ot_macrolanguage] - if 'retired code' not in bcp_47.scopes.get (l, '') - } - round_trip_languages = { - l for l in languages - if 'retired code' not in bcp_47.scopes.get (l, '') - } - intersection = round_trip_macrolanguages & round_trip_languages - if intersection and intersection != round_trip_languages: - blocked_ot_macrolanguages.add (ot_macrolanguage) - if ot_macrolanguages: - for ot_macrolanguage in ot_macrolanguages: - if ot_macrolanguage not in blocked_ot_macrolanguages: - for language in languages: - self.add_language (language, ot_macrolanguage) - if not blocked_ot_macrolanguages: - self.ranks[ot_macrolanguage] += 1 - elif first_time: - for language in languages: - if language in self.from_bcp_47_uninherited: - ot_macrolanguages |= self.from_bcp_47_uninherited[language] - else: - ot_macrolanguages.clear () - if not ot_macrolanguages: - break - for ot_macrolanguage in ot_macrolanguages: - self.add_language (macrolanguage, ot_macrolanguage) - - def sort_languages (self): - """Sort the values of ``from_bcp_47`` in ascending rank order.""" - for language, tags in self.from_bcp_47.items (): - self.from_bcp_47[language] = sorted (tags, - key=lambda t: (self.ranks[t] + rank_delta (language, t), t)) - -ot = OpenTypeRegistryParser () - -class BCP47Parser (object): - """A parser for the BCP 47 subtag registry. - - Attributes: - header (str): The "File-Date" line of the registry. - names (Mapping[str, str]): A map of subtags to the names they - are given in the registry. Each value is a - ``'\\n'``-separated list of names. - scopes (Mapping[str, str]): A map of language subtags to strings - suffixed to language names, including suffixes to explain - language scopes. - macrolanguages (DefaultDict[str, AbstractSet[str]]): A map of - language subtags to the sets of language subtags which - inherit from them. See - ``OpenTypeRegistryParser.inherit_from_macrolanguages``. - prefixes (DefaultDict[str, AbstractSet[str]]): A map of variant - subtags to their prefixes. - grandfathered (AbstractSet[str]): The set of grandfathered tags, - normalized to lowercase. - - """ - def __init__ (self): - self.header = '' - self.names = {} - self.scopes = {} - self.macrolanguages = collections.defaultdict (set) - self.prefixes = collections.defaultdict (set) - self.grandfathered = set () - - def parse (self, filename): - """Parse the BCP 47 subtag registry. - - Args: - filename (str): The file name of the registry. - """ - with open (filename, encoding='utf-8') as f: - subtag_type = None - subtag = None - deprecated = False - has_preferred_value = False - line_buffer = '' - for line in itertools.chain (f, ['']): - line = line.rstrip () - if line.startswith (' '): - line_buffer += line[1:] - continue - line, line_buffer = line_buffer, line - if line.startswith ('Type: '): - subtag_type = line.split (' ')[1] - deprecated = False - has_preferred_value = False - elif line.startswith ('Subtag: ') or line.startswith ('Tag: '): - subtag = line.split (' ')[1] - if subtag_type == 'grandfathered': - self.grandfathered.add (subtag.lower ()) - elif line.startswith ('Description: '): - description = line.split (' ', 1)[1].replace (' (individual language)', '') - description = re.sub (' (\(family\)|\((individual |macro)language\)|languages)$', '', - description) - if subtag in self.names: - self.names[subtag] += '\n' + description - else: - self.names[subtag] = description - elif subtag_type == 'language' or subtag_type == 'grandfathered': - if line.startswith ('Scope: '): - scope = line.split (' ')[1] - if scope == 'macrolanguage': - scope = ' [macrolanguage]' - elif scope == 'collection': - scope = ' [collection]' - else: - continue - self.scopes[subtag] = scope - elif line.startswith ('Deprecated: '): - self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') - deprecated = True - elif deprecated and line.startswith ('Comments: see '): - # If a subtag is split into multiple replacement subtags, - # it essentially represents a macrolanguage. - for language in line.replace (',', '').split (' ')[2:]: - self._add_macrolanguage (subtag, language) - elif line.startswith ('Preferred-Value: '): - # If a subtag is deprecated in favor of a single replacement subtag, - # it is either a dialect or synonym of the preferred subtag. Either - # way, it is close enough to the truth to consider the replacement - # the macrolanguage of the deprecated language. - has_preferred_value = True - macrolanguage = line.split (' ')[1] - self._add_macrolanguage (macrolanguage, subtag) - elif not has_preferred_value and line.startswith ('Macrolanguage: '): - self._add_macrolanguage (line.split (' ')[1], subtag) - elif subtag_type == 'variant': - if line.startswith ('Deprecated: '): - self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') - elif line.startswith ('Prefix: '): - self.prefixes[subtag].add (line.split (' ')[1]) - elif line.startswith ('File-Date: '): - self.header = line - expect (self.header) - - def _add_macrolanguage (self, macrolanguage, language): - global ot - if language not in ot.from_bcp_47: - for l in self.macrolanguages.get (language, set ()): - self._add_macrolanguage (macrolanguage, l) - if macrolanguage not in ot.from_bcp_47: - for ls in list (self.macrolanguages.values ()): - if macrolanguage in ls: - ls.add (language) - return - self.macrolanguages[macrolanguage].add (language) - - def remove_extra_macrolanguages (self): - """Make every language have at most one macrolanguage.""" - inverted = collections.defaultdict (list) - for macrolanguage, languages in self.macrolanguages.items (): - for language in languages: - inverted[language].append (macrolanguage) - for language, macrolanguages in inverted.items (): - if len (macrolanguages) > 1: - macrolanguages.sort (key=lambda ml: len (self.macrolanguages[ml])) - biggest_macrolanguage = macrolanguages.pop () - for macrolanguage in macrolanguages: - self._add_macrolanguage (biggest_macrolanguage, macrolanguage) - - def _get_name_piece (self, subtag): - """Return the first name of a subtag plus its scope suffix. - - Args: - subtag (str): A BCP 47 subtag. - - Returns: - The name form of ``subtag``. - """ - return self.names[subtag].split ('\n')[0] + self.scopes.get (subtag, '') - - def get_name (self, lt): - """Return the names of the subtags in a language tag. - - Args: - lt (LanguageTag): A BCP 47 language tag. - - Returns: - The name form of ``lt``. - """ - name = self._get_name_piece (lt.language) - if lt.script: - name += '; ' + self._get_name_piece (lt.script.title ()) - if lt.region: - name += '; ' + self._get_name_piece (lt.region.upper ()) - if lt.variant: - name += '; ' + self._get_name_piece (lt.variant) - return name - -bcp_47 = BCP47Parser () - -ot.parse (sys.argv[1]) -bcp_47.parse (sys.argv[2]) - -ot.add_language ('ary', 'MOR') - -ot.add_language ('ath', 'ATH') - -ot.add_language ('bai', 'BML') - -ot.ranks['BAL'] = ot.ranks['KAR'] + 1 - -ot.add_language ('ber', 'BBR') - -ot.remove_language_ot ('PGR') -ot.add_language ('el-polyton', 'PGR') - -bcp_47.macrolanguages['et'] = {'ekk'} - -bcp_47.names['flm'] = 'Falam Chin' -bcp_47.scopes['flm'] = ' (retired code)' -bcp_47.macrolanguages['flm'] = {'cfm'} - -ot.ranks['FNE'] = ot.ranks['TNE'] + 1 - -ot.add_language ('und-fonipa', 'IPPH') - -ot.add_language ('und-fonnapa', 'APPH') - -ot.remove_language_ot ('IRT') -ot.add_language ('ga-Latg', 'IRT') - -ot.add_language ('hy-arevmda', 'HYE') - -ot.remove_language_ot ('KGE') -ot.add_language ('und-Geok', 'KGE') - -bcp_47.macrolanguages['id'] = {'in'} - -bcp_47.macrolanguages['ijo'] = {'ijc'} - -ot.add_language ('kht', 'KHN') -ot.names['KHN'] = ot.names['KHT'] + ' (Microsoft fonts)' -ot.ranks['KHN'] = ot.ranks['KHT'] + 1 - -ot.ranks['LCR'] = ot.ranks['MCR'] + 1 - -ot.names['MAL'] = 'Malayalam Traditional' -ot.ranks['MLR'] += 1 - -bcp_47.names['mhv'] = 'Arakanese' -bcp_47.scopes['mhv'] = ' (retired code)' - -ot.add_language ('mnw-TH', 'MONT') - -ot.add_language ('no', 'NOR') - -ot.add_language ('oc-provenc', 'PRO') - -ot.remove_language_ot ('QUZ') -ot.add_language ('qu', 'QUZ') -ot.add_language ('qub', 'QWH') -ot.add_language ('qud', 'QVI') -ot.add_language ('qug', 'QVI') -ot.add_language ('qul', 'QUH') -ot.add_language ('qup', 'QVI') -ot.add_language ('qur', 'QWH') -ot.add_language ('qus', 'QUH') -ot.add_language ('quw', 'QVI') -ot.add_language ('qux', 'QWH') -ot.add_language ('qva', 'QWH') -ot.add_language ('qvh', 'QWH') -ot.add_language ('qvj', 'QVI') -ot.add_language ('qvl', 'QWH') -ot.add_language ('qvm', 'QWH') -ot.add_language ('qvn', 'QWH') -ot.add_language ('qvo', 'QVI') -ot.add_language ('qvp', 'QWH') -ot.add_language ('qvw', 'QWH') -ot.add_language ('qvz', 'QVI') -ot.add_language ('qwa', 'QWH') -ot.add_language ('qws', 'QWH') -ot.add_language ('qxa', 'QWH') -ot.add_language ('qxc', 'QWH') -ot.add_language ('qxh', 'QWH') -ot.add_language ('qxl', 'QVI') -ot.add_language ('qxn', 'QWH') -ot.add_language ('qxo', 'QWH') -ot.add_language ('qxr', 'QVI') -ot.add_language ('qxt', 'QWH') -ot.add_language ('qxw', 'QWH') - -bcp_47.macrolanguages['ro-MD'].add ('mo') - -ot.remove_language_ot ('SYRE') -ot.remove_language_ot ('SYRJ') -ot.remove_language_ot ('SYRN') -ot.add_language ('und-Syre', 'SYRE') -ot.add_language ('und-Syrj', 'SYRJ') -ot.add_language ('und-Syrn', 'SYRN') - -bcp_47.names['xst'] = "Silt'e" -bcp_47.scopes['xst'] = ' (retired code)' -bcp_47.macrolanguages['xst'] = {'stv', 'wle'} - -ot.add_language ('xwo', 'TOD') - -ot.remove_language_ot ('ZHH') -ot.remove_language_ot ('ZHP') -ot.remove_language_ot ('ZHT') -ot.remove_language_ot ('ZHTM') -bcp_47.macrolanguages['zh'].remove ('lzh') -bcp_47.macrolanguages['zh'].remove ('yue') -ot.add_language ('zh-Hant-MO', 'ZHH') -ot.add_language ('zh-Hant-MO', 'ZHTM') -ot.add_language ('zh-Hant-HK', 'ZHH') -ot.add_language ('zh-Hans', 'ZHS') -ot.add_language ('zh-Hant', 'ZHT') -ot.add_language ('zh-HK', 'ZHH') -ot.add_language ('zh-MO', 'ZHH') -ot.add_language ('zh-MO', 'ZHTM') -ot.add_language ('zh-TW', 'ZHT') -ot.add_language ('lzh', 'ZHT') -ot.add_language ('lzh-Hans', 'ZHS') -ot.add_language ('yue', 'ZHH') -ot.add_language ('yue-Hans', 'ZHS') - -bcp_47.macrolanguages['zom'] = {'yos'} - -def rank_delta (bcp_47, ot): - """Return a delta to apply to a BCP 47 tag's rank. - - Most OpenType tags have a constant rank, but a few have ranks that - depend on the BCP 47 tag. - - Args: - bcp_47 (str): A BCP 47 tag. - ot (str): An OpenType tag to. - - Returns: - A number to add to ``ot``'s rank when sorting ``bcp_47``'s - OpenType equivalents. - """ - if bcp_47 == 'ak' and ot == 'AKA': - return -1 - if bcp_47 == 'tw' and ot == 'TWI': - return -1 - return 0 - -disambiguation = { - 'ALT': 'alt', - 'ARK': 'rki', - 'ATH': 'ath', - 'BHI': 'bhb', - 'BLN': 'bjt', - 'BTI': 'beb', - 'CCHN': 'cco', - 'CMR': 'swb', - 'CPP': 'crp', - 'CRR': 'crx', - 'DUJ': 'dwu', - 'ECR': 'crj', - 'HAL': 'cfm', - 'HND': 'hnd', - 'HYE': 'hyw', - 'KIS': 'kqs', - 'KUI': 'uki', - 'LRC': 'bqi', - 'NDB': 'nd', - 'NIS': 'njz', - 'PLG': 'pce', - 'PRO': 'pro', - 'QIN': 'bgr', - 'QUH': 'quh', - 'QVI': 'qvi', - 'QWH': 'qwh', - 'SIG': 'stv', - 'SRB': 'sr', - 'SXT': 'xnj', - 'ZHH': 'zh-HK', - 'ZHS': 'zh-Hans', - 'ZHT': 'zh-Hant', - 'ZHTM': 'zh-MO', -} - -ot.inherit_from_macrolanguages () -bcp_47.remove_extra_macrolanguages () -ot.inherit_from_macrolanguages () -ot.names[DEFAULT_LANGUAGE_SYSTEM] = '*/' -ot.ranks[DEFAULT_LANGUAGE_SYSTEM] = max (ot.ranks.values ()) + 1 -for tricky_ot_tag in filter (lambda tag: re.match ('[A-Z]{3}$', tag), ot.names): - possible_bcp_47_tag = tricky_ot_tag.lower () - if possible_bcp_47_tag in bcp_47.names and not ot.from_bcp_47[possible_bcp_47_tag]: - ot.add_language (possible_bcp_47_tag, DEFAULT_LANGUAGE_SYSTEM) - bcp_47.macrolanguages[possible_bcp_47_tag] = set () -ot.sort_languages () - -print ('/* == Start of generated table == */') -print ('/*') -print (' * The following table is generated by running:') -print (' *') -print (' * %s languagetags language-subtag-registry' % sys.argv[0]) -print (' *') -print (' * on files with these headers:') -print (' *') -print (' * %s' % ot.header.strip ()) -print (' * %s' % bcp_47.header) -print (' */') -print () -print ('#ifndef HB_OT_TAG_TABLE_HH') -print ('#define HB_OT_TAG_TABLE_HH') -print () - -def hb_tag (tag): - """Convert a tag to ``HB_TAG`` form. - - Args: - tag (str): An OpenType tag. - - Returns: - A snippet of C++ representing ``tag``. - """ - if tag == DEFAULT_LANGUAGE_SYSTEM: - return 'HB_TAG_NONE\t ' - return "HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4]) - -def get_variant_set (name): - """Return a set of variant language names from a name. - - Args: - name (str): A list of language names from the BCP 47 registry, - joined on ``'\\n'``. - - Returns: - A set of normalized language names. - """ - return set (unicodedata.normalize ('NFD', n.replace ('\u2019', "'")) - .encode ('ASCII', 'ignore') - .strip () - for n in re.split ('[\n(),]', name) if n) - -def language_name_intersection (a, b): - """Return the names in common between two language names. - - Args: - a (str): A list of language names from the BCP 47 registry, - joined on ``'\\n'``. - b (str): A list of language names from the BCP 47 registry, - joined on ``'\\n'``. - - Returns: - The normalized language names shared by ``a`` and ``b``. - """ - return get_variant_set (a).intersection (get_variant_set (b)) - -def get_matching_language_name (intersection, candidates): - return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) - -def same_tag (bcp_47_tag, ot_tags): - return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower () - -for language_len in (2, 3): - if language_len == 3: - print ('#ifndef HB_NO_LANGUAGE_LONG') - print ('static const LangTag ot_languages%d[] = {' % language_len) - for language, tags in sorted (ot.from_bcp_47.items ()): - if language == '' or '-' in language: - continue - if len(language) != language_len: continue - commented_out = same_tag (language, tags) - for i, tag in enumerate (tags, start=1): - print ('%s{%s,\t%s},' % ('/*' if commented_out else ' ', hb_tag (language), hb_tag (tag)), end='') - if commented_out: - print ('*/', end='') - print ('\t/* ', end='') - bcp_47_name = bcp_47.names.get (language, '') - bcp_47_name_candidates = bcp_47_name.split ('\n') - ot_name = ot.names[tag] - scope = bcp_47.scopes.get (language, '') - if tag == DEFAULT_LANGUAGE_SYSTEM: - write (f'{bcp_47_name_candidates[0]}{scope} != {ot.names[language.upper ()]}') - else: - intersection = language_name_intersection (bcp_47_name, ot_name) - if not intersection: - write ('%s%s -> %s' % (bcp_47_name_candidates[0], scope, ot_name)) - else: - name = get_matching_language_name (intersection, bcp_47_name_candidates) - bcp_47.names[language] = name - write ('%s%s' % (name if len (name) > len (ot_name) else ot_name, scope)) - print (' */') - print ('};') - if language_len == 3: - print ('#endif') - print () - -print ('/**') -print (' * hb_ot_tags_from_complex_language:') -print (' * @lang_str: a BCP 47 language tag to convert.') -print (' * @limit: a pointer to the end of the substring of @lang_str to consider for') -print (' * conversion.') -print (' * @count: maximum number of language tags to retrieve (IN) and actual number of') -print (' * language tags retrieved (OUT). If no tags are retrieved, it is not modified.') -print (' * @tags: array of size at least @language_count to store the language tag') -print (' * results') -print (' *') -print (' * Converts a multi-subtag BCP 47 language tag to language tags.') -print (' *') -print (' * Return value: Whether any language systems were retrieved.') -print (' **/') -print ('static inline bool') -print ('hb_ot_tags_from_complex_language (const char *lang_str,') -print ('\t\t\t\t const char *limit,') -print ('\t\t\t\t unsigned int *count /* IN/OUT */,') -print ('\t\t\t\t hb_tag_t *tags /* OUT */)') -print ('{') - -def print_subtag_matches (subtag, string, new_line): - if subtag: - if new_line: - print () - print ('\t&& ', end='') - print ('subtag_matches (%s, limit, "-%s", %i)' % (string, subtag, 1 + len (subtag)), end='') - -complex_tags = collections.defaultdict (list) -for initial, group in itertools.groupby ((lt_tags for lt_tags in [ - (LanguageTag (language), tags) - for language, tags in sorted (ot.from_bcp_47.items (), - key=lambda i: (-len (i[0]), i[0])) - ] if lt_tags[0].is_complex ()), - key=lambda lt_tags: lt_tags[0].get_group ()): - complex_tags[initial] += group - -# Calculate the min length of the subtags outside the switch -min_subtag_len = 100 -for initial, items in sorted (complex_tags.items ()): - if initial != 'und': - continue - for lt, tags in items: - if not tags: - continue - subtag_len = 0 - subtag_len += 1 + len (lt.script) if lt.script is not None else 0 - subtag_len += 1 + len (lt.region) if lt.region is not None else 0 - subtag_len += 1 + len (lt.variant) if lt.variant is not None else 0 - min_subtag_len = min(subtag_len, min_subtag_len) - -print (' if (limit - lang_str >= %d)' % (min_subtag_len + 2)) -print (' {') -print (" const char *p = strchr (lang_str, '-');") -print (" if (!p || p >= limit || limit - p < %i) goto out;" % min_subtag_len) -for initial, items in sorted (complex_tags.items ()): - if initial != 'und': - continue - for lt, tags in items: - if not tags: - continue - if lt.variant in bcp_47.prefixes: - expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language, - '%s is not a valid prefix of %s' % (lt.language, lt.variant)) - print (' if (', end='') - print_subtag_matches (lt.script, 'p', False) - print_subtag_matches (lt.region, 'p', False) - print_subtag_matches (lt.variant, 'p', False) - print (')') - print (' {') - write (' /* %s */' % bcp_47.get_name (lt)) - print () - if len (tags) == 1: - write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) - print () - print (' *count = 1;') - else: - print (' hb_tag_t possible_tags[] = {') - for tag in tags: - write (' %s, /* %s */' % (hb_tag (tag), ot.names[tag])) - print () - print (' };') - print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) - print ('\ttags[i] = possible_tags[i];') - print (' *count = i;') - print (' return true;') - print (' }') -print (' }') -print ('out:') - -print (' switch (lang_str[0])') -print (' {') -for initial, items in sorted (complex_tags.items ()): - if initial == 'und': - continue - print (" case '%s':" % initial) - for lt, tags in items: - if not tags: - continue - print (' if (', end='') - script = lt.script - region = lt.region - if lt.grandfathered: - print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='') - else: - string_literal = lt.language[1:] + '-' - if script: - string_literal += script - script = None - if region: - string_literal += '-' + region - region = None - if string_literal[-1] == '-': - print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='') - else: - print ('lang_matches (&lang_str[1], limit, "%s", %i)' % (string_literal, len (string_literal)), end='') - print_subtag_matches (script, 'lang_str', True) - print_subtag_matches (region, 'lang_str', True) - print_subtag_matches (lt.variant, 'lang_str', True) - print (')') - print (' {') - write (' /* %s */' % bcp_47.get_name (lt)) - print () - if len (tags) == 1: - write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) - print () - print (' *count = 1;') - else: - print (' unsigned int i;') - print (' hb_tag_t possible_tags[] = {') - for tag in tags: - write ('\t%s, /* %s */' % (hb_tag (tag), ot.names[tag])) - print () - print (' };') - print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) - print ('\ttags[i] = possible_tags[i];') - print (' *count = i;') - print (' return true;') - print (' }') - print (' break;') - -print (' }') -print (' return false;') -print ('}') -print () -print ('/**') -print (' * hb_ot_ambiguous_tag_to_language') -print (' * @tag: A language tag.') -print (' *') -print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to') -print (' * many language tags) and the best tag is not the alphabetically first, or if') -print (' * the best tag consists of multiple subtags, or if the best tag does not appear') -print (' * in #ot_languages.') -print (' *') -print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') -print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') -print (' **/') -print ('static inline hb_language_t') -print ('hb_ot_ambiguous_tag_to_language (hb_tag_t tag)') -print ('{') -print (' switch (tag)') -print (' {') - -def verify_disambiguation_dict (): - """Verify and normalize ``disambiguation``. - - ``disambiguation`` is a map of ambiguous OpenType language system - tags to the particular BCP 47 tags they correspond to. This function - checks that all its keys really are ambiguous and that each key's - value is valid for that key. It checks that no ambiguous tag is - missing, except when it can figure out which BCP 47 tag is the best - by itself. - - It modifies ``disambiguation`` to remove keys whose values are the - same as those that the fallback would return anyway, and to add - ambiguous keys whose disambiguations it determined automatically. - - Raises: - AssertionError: Verification failed. - """ - global bcp_47 - global disambiguation - global ot - for ot_tag, bcp_47_tags in ot.to_bcp_47.items (): - if ot_tag == DEFAULT_LANGUAGE_SYSTEM: - primary_tags = [] - else: - primary_tags = list (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot.from_bcp_47.get (t)[0] == ot_tag) - if len (primary_tags) == 1: - expect (ot_tag not in disambiguation, 'unnecessary disambiguation for OT tag: %s' % ot_tag) - if '-' in primary_tags[0]: - disambiguation[ot_tag] = primary_tags[0] - else: - first_tag = sorted (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot_tag in ot.from_bcp_47.get (t))[0] - if primary_tags[0] != first_tag: - disambiguation[ot_tag] = primary_tags[0] - elif len (primary_tags) == 0: - expect (ot_tag not in disambiguation, 'There is no possible valid disambiguation for %s' % ot_tag) - else: - original_languages = [t for t in primary_tags if t in ot.from_bcp_47_uninherited and 'retired code' not in bcp_47.scopes.get (t, '')] - if len (original_languages) == 1: - macrolanguages = original_languages - else: - macrolanguages = [t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]'] - if len (macrolanguages) != 1: - macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [collection]') - if len (macrolanguages) != 1: - macrolanguages = list (t for t in primary_tags if 'retired code' not in bcp_47.scopes.get (t, '')) - if len (macrolanguages) != 1: - expect (ot_tag in disambiguation, 'ambiguous OT tag: %s %s' % (ot_tag, str (macrolanguages))) - expect (disambiguation[ot_tag] in bcp_47_tags, - '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) - elif ot_tag not in disambiguation: - disambiguation[ot_tag] = macrolanguages[0] - different_bcp_47_tags = sorted (t for t in bcp_47_tags if not same_tag (t, ot.from_bcp_47.get (t))) - if different_bcp_47_tags and disambiguation[ot_tag] == different_bcp_47_tags[0] and '-' not in disambiguation[ot_tag]: - del disambiguation[ot_tag] - for ot_tag in disambiguation.keys (): - expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) - -verify_disambiguation_dict () -for ot_tag, bcp_47_tag in sorted (disambiguation.items ()): - write (' case %s: /* %s */' % (hb_tag (ot_tag), ot.names[ot_tag])) - print () - write (' return hb_language_from_string (\"%s\", -1); /* %s */' % (bcp_47_tag, bcp_47.get_name (LanguageTag (bcp_47_tag)))) - print () - -print (' default:') -print (' return HB_LANGUAGE_INVALID;') -print (' }') -print ('}') - -print () -print ('#endif /* HB_OT_TAG_TABLE_HH */') -print () -print ('/* == End of generated table == */') - +#!/usr/bin/env python3 + +"""Generator of the mapping from OpenType tags to BCP 47 tags and vice +versa. + +It creates a ``const LangTag[]``, matching the tags from the OpenType +languages system tag list to the language subtags of the BCP 47 language +subtag registry, with some manual adjustments. The mappings are +supplemented with macrolanguages' sublanguages and retired codes' +replacements, according to BCP 47 and some manual additions where BCP 47 +omits a retired code entirely. + +Also generated is a function, ``hb_ot_ambiguous_tag_to_language``, +intended for use by ``hb_ot_tag_to_language``. It maps OpenType tags +back to BCP 47 tags. Ambiguous OpenType tags (those that correspond to +multiple BCP 47 tags) are listed here, except when the alphabetically +first BCP 47 tag happens to be the chosen disambiguated tag. In that +case, the fallback behavior will choose the right tag anyway. + +usage: ./gen-tag-table.py languagetags language-subtag-registry + +Input files: +* https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags +* https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +""" + +import collections +import html +from html.parser import HTMLParser +import itertools +import re +import sys +import unicodedata + +if len (sys.argv) != 3: + sys.exit (__doc__) + +def expect (condition, message=None): + if not condition: + if message is None: + raise AssertionError + raise AssertionError (message) + +def write (s): + sys.stdout.flush () + sys.stdout.buffer.write (s.encode ('utf-8')) + +DEFAULT_LANGUAGE_SYSTEM = '' + +# from https://www-01.sil.org/iso639-3/iso-639-3.tab +ISO_639_3_TO_1 = { + 'aar': 'aa', + 'abk': 'ab', + 'afr': 'af', + 'aka': 'ak', + 'amh': 'am', + 'ara': 'ar', + 'arg': 'an', + 'asm': 'as', + 'ava': 'av', + 'ave': 'ae', + 'aym': 'ay', + 'aze': 'az', + 'bak': 'ba', + 'bam': 'bm', + 'bel': 'be', + 'ben': 'bn', + 'bis': 'bi', + 'bod': 'bo', + 'bos': 'bs', + 'bre': 'br', + 'bul': 'bg', + 'cat': 'ca', + 'ces': 'cs', + 'cha': 'ch', + 'che': 'ce', + 'chu': 'cu', + 'chv': 'cv', + 'cor': 'kw', + 'cos': 'co', + 'cre': 'cr', + 'cym': 'cy', + 'dan': 'da', + 'deu': 'de', + 'div': 'dv', + 'dzo': 'dz', + 'ell': 'el', + 'eng': 'en', + 'epo': 'eo', + 'est': 'et', + 'eus': 'eu', + 'ewe': 'ee', + 'fao': 'fo', + 'fas': 'fa', + 'fij': 'fj', + 'fin': 'fi', + 'fra': 'fr', + 'fry': 'fy', + 'ful': 'ff', + 'gla': 'gd', + 'gle': 'ga', + 'glg': 'gl', + 'glv': 'gv', + 'grn': 'gn', + 'guj': 'gu', + 'hat': 'ht', + 'hau': 'ha', + 'hbs': 'sh', + 'heb': 'he', + 'her': 'hz', + 'hin': 'hi', + 'hmo': 'ho', + 'hrv': 'hr', + 'hun': 'hu', + 'hye': 'hy', + 'ibo': 'ig', + 'ido': 'io', + 'iii': 'ii', + 'iku': 'iu', + 'ile': 'ie', + 'ina': 'ia', + 'ind': 'id', + 'ipk': 'ik', + 'isl': 'is', + 'ita': 'it', + 'jav': 'jv', + 'jpn': 'ja', + 'kal': 'kl', + 'kan': 'kn', + 'kas': 'ks', + 'kat': 'ka', + 'kau': 'kr', + 'kaz': 'kk', + 'khm': 'km', + 'kik': 'ki', + 'kin': 'rw', + 'kir': 'ky', + 'kom': 'kv', + 'kon': 'kg', + 'kor': 'ko', + 'kua': 'kj', + 'kur': 'ku', + 'lao': 'lo', + 'lat': 'la', + 'lav': 'lv', + 'lim': 'li', + 'lin': 'ln', + 'lit': 'lt', + 'ltz': 'lb', + 'lub': 'lu', + 'lug': 'lg', + 'mah': 'mh', + 'mal': 'ml', + 'mar': 'mr', + 'mkd': 'mk', + 'mlg': 'mg', + 'mlt': 'mt', + 'mol': 'mo', + 'mon': 'mn', + 'mri': 'mi', + 'msa': 'ms', + 'mya': 'my', + 'nau': 'na', + 'nav': 'nv', + 'nbl': 'nr', + 'nde': 'nd', + 'ndo': 'ng', + 'nep': 'ne', + 'nld': 'nl', + 'nno': 'nn', + 'nob': 'nb', + 'nor': 'no', + 'nya': 'ny', + 'oci': 'oc', + 'oji': 'oj', + 'ori': 'or', + 'orm': 'om', + 'oss': 'os', + 'pan': 'pa', + 'pli': 'pi', + 'pol': 'pl', + 'por': 'pt', + 'pus': 'ps', + 'que': 'qu', + 'roh': 'rm', + 'ron': 'ro', + 'run': 'rn', + 'rus': 'ru', + 'sag': 'sg', + 'san': 'sa', + 'sin': 'si', + 'slk': 'sk', + 'slv': 'sl', + 'sme': 'se', + 'smo': 'sm', + 'sna': 'sn', + 'snd': 'sd', + 'som': 'so', + 'sot': 'st', + 'spa': 'es', + 'sqi': 'sq', + 'srd': 'sc', + 'srp': 'sr', + 'ssw': 'ss', + 'sun': 'su', + 'swa': 'sw', + 'swe': 'sv', + 'tah': 'ty', + 'tam': 'ta', + 'tat': 'tt', + 'tel': 'te', + 'tgk': 'tg', + 'tgl': 'tl', + 'tha': 'th', + 'tir': 'ti', + 'ton': 'to', + 'tsn': 'tn', + 'tso': 'ts', + 'tuk': 'tk', + 'tur': 'tr', + 'twi': 'tw', + 'uig': 'ug', + 'ukr': 'uk', + 'urd': 'r', + 'uzb': 'uz', + 'ven': 've', + 'vie': 'vi', + 'vol': 'vo', + 'wln': 'wa', + 'wol': 'wo', + 'xho': 'xh', + 'yid': 'yi', + 'yor': 'yo', + 'zha': 'za', + 'zho': 'zh', + 'zul': 'zu', +} + +class LanguageTag (object): + """A BCP 47 language tag. + + Attributes: + subtags (List[str]): The list of subtags in this tag. + grandfathered (bool): Whether this tag is grandfathered. If + ``true``, the entire lowercased tag is the ``language`` + and the other subtag fields are empty. + language (str): The language subtag. + script (str): The script subtag. + region (str): The region subtag. + variant (str): The variant subtag. + + Args: + tag (str): A BCP 47 language tag. + + """ + def __init__ (self, tag): + global bcp_47 + self.subtags = tag.lower ().split ('-') + self.grandfathered = tag.lower () in bcp_47.grandfathered + if self.grandfathered: + self.language = tag.lower () + self.script = '' + self.region = '' + self.variant = '' + else: + self.language = self.subtags[0] + self.script = self._find_first (lambda s: len (s) == 4 and s[0] > '9', self.subtags) + self.region = self._find_first (lambda s: len (s) == 2 and s[0] > '9' or len (s) == 3 and s[0] <= '9', self.subtags[1:]) + self.variant = self._find_first (lambda s: len (s) > 4 or len (s) == 4 and s[0] <= '9', self.subtags) + + def __str__(self): + return '-'.join(self.subtags) + + def __repr__ (self): + return 'LanguageTag(%r)' % str(self) + + @staticmethod + def _find_first (function, sequence): + try: + return next (iter (filter (function, sequence))) + except StopIteration: + return None + + def is_complex (self): + """Return whether this tag is too complex to represent as a + ``LangTag`` in the generated code. + + Complex tags need to be handled in + ``hb_ot_tags_from_complex_language``. + + Returns: + Whether this tag is complex. + """ + return not (len (self.subtags) == 1 + or self.grandfathered + and len (self.subtags[1]) != 3 + and ot.from_bcp_47[self.subtags[0]] == ot.from_bcp_47[self.language]) + + def get_group (self): + """Return the group into which this tag should be categorized in + ``hb_ot_tags_from_complex_language``. + + The group is the first letter of the tag, or ``'und'`` if this tag + should not be matched in a ``switch`` statement in the generated + code. + + Returns: + This tag's group. + """ + return ('und' + if (self.language == 'und' + or self.variant in bcp_47.prefixes and len (bcp_47.prefixes[self.variant]) == 1) + else self.language[0]) + +class OpenTypeRegistryParser (HTMLParser): + """A parser for the OpenType language system tag registry. + + Attributes: + header (str): The "last updated" line of the registry. + names (Mapping[str, str]): A map of language system tags to the + names they are given in the registry. + ranks (DefaultDict[str, int]): A map of language system tags to + numbers. If a single BCP 47 tag corresponds to multiple + OpenType tags, the tags are ordered in increasing order by + rank. The rank is based on the number of BCP 47 tags + associated with a tag, though it may be manually modified. + to_bcp_47 (DefaultDict[str, AbstractSet[str]]): A map of + OpenType language system tags to sets of BCP 47 tags. + from_bcp_47 (DefaultDict[str, AbstractSet[str]]): ``to_bcp_47`` + inverted. Its values start as unsorted sets; + ``sort_languages`` converts them to sorted lists. + from_bcp_47_uninherited (Optional[Dict[str, AbstractSet[str]]]): + A copy of ``from_bcp_47``. It starts as ``None`` and is + populated at the beginning of the first call to + ``inherit_from_macrolanguages``. + + """ + def __init__ (self): + HTMLParser.__init__ (self) + self.header = '' + self.names = {} + self.ranks = collections.defaultdict (int) + self.to_bcp_47 = collections.defaultdict (set) + self.from_bcp_47 = collections.defaultdict (set) + self.from_bcp_47_uninherited = None + # Whether the parser is in a element + self._td = False + # Whether the parser is after a
element within the current element + self._br = False + # The text of the elements of the current element. + self._current_tr = [] + + def handle_starttag (self, tag, attrs): + if tag == 'br': + self._br = True + elif tag == 'meta': + for attr, value in attrs: + if attr == 'name' and value == 'updated_at': + self.header = self.get_starttag_text () + break + elif tag == 'td': + self._td = True + self._current_tr.append ('') + elif tag == 'tr': + self._br = False + self._current_tr = [] + + def handle_endtag (self, tag): + if tag == 'td': + self._td = False + elif tag == 'tr' and self._current_tr: + expect (2 <= len (self._current_tr) <= 3) + name = self._current_tr[0].strip () + tag = self._current_tr[1].strip ("\t\n\v\f\r '") + rank = 0 + if len (tag) > 4: + expect (tag.endswith (' (deprecated)'), 'ill-formed OpenType tag: %s' % tag) + name += ' (deprecated)' + tag = tag.split (' ')[0] + rank = 1 + self.names[tag] = re.sub (' languages$', '', name) + if not self._current_tr[2]: + return + iso_codes = self._current_tr[2].strip () + self.to_bcp_47[tag].update (ISO_639_3_TO_1.get (code, code) for code in iso_codes.replace (' ', '').split (',')) + rank += 2 * len (self.to_bcp_47[tag]) + self.ranks[tag] = rank + + def handle_data (self, data): + if self._td and not self._br: + self._current_tr[-1] += data + + def handle_charref (self, name): + self.handle_data (html.unescape ('&#%s;' % name)) + + def handle_entityref (self, name): + self.handle_data (html.unescape ('&%s;' % name)) + + def parse (self, filename): + """Parse the OpenType language system tag registry. + + Args: + filename (str): The file name of the registry. + """ + with open (filename, encoding='utf-8') as f: + self.feed (f.read ()) + expect (self.header) + for tag, iso_codes in self.to_bcp_47.items (): + for iso_code in iso_codes: + self.from_bcp_47[iso_code].add (tag) + + def add_language (self, bcp_47_tag, ot_tag): + """Add a language as if it were in the registry. + + Args: + bcp_47_tag (str): A BCP 47 tag. If the tag is more than just + a language subtag, and if the language subtag is a + macrolanguage, then new languages are added corresponding + to the macrolanguages' individual languages with the + remainder of the tag appended. + ot_tag (str): An OpenType language system tag. + """ + global bcp_47 + self.to_bcp_47[ot_tag].add (bcp_47_tag) + self.from_bcp_47[bcp_47_tag].add (ot_tag) + if bcp_47_tag.lower () not in bcp_47.grandfathered: + try: + [macrolanguage, suffix] = bcp_47_tag.split ('-', 1) + if macrolanguage in bcp_47.macrolanguages: + s = set () + for language in bcp_47.macrolanguages[macrolanguage]: + if language.lower () not in bcp_47.grandfathered: + s.add ('%s-%s' % (language, suffix)) + bcp_47.macrolanguages['%s-%s' % (macrolanguage, suffix)] = s + except ValueError: + pass + + @staticmethod + def _remove_language (tag_1, dict_1, dict_2): + for tag_2 in dict_1.pop (tag_1): + dict_2[tag_2].remove (tag_1) + if not dict_2[tag_2]: + del dict_2[tag_2] + + def remove_language_ot (self, ot_tag): + """Remove an OpenType tag from the registry. + + Args: + ot_tag (str): An OpenType tag. + """ + self._remove_language (ot_tag, self.to_bcp_47, self.from_bcp_47) + + def remove_language_bcp_47 (self, bcp_47_tag): + """Remove a BCP 47 tag from the registry. + + Args: + bcp_47_tag (str): A BCP 47 tag. + """ + self._remove_language (bcp_47_tag, self.from_bcp_47, self.to_bcp_47) + + def inherit_from_macrolanguages (self): + """Copy mappings from macrolanguages to individual languages. + + If a BCP 47 tag for an individual mapping has no OpenType + mapping but its macrolanguage does, the mapping is copied to + the individual language. For example, als (Tosk Albanian) has no + explicit mapping, so it inherits from sq (Albanian) the mapping + to SQI. + + However, if an OpenType tag maps to a BCP 47 macrolanguage and + some but not all of its individual languages, the mapping is not + inherited from the macrolanguage to the missing individual + languages. For example, INUK (Nunavik Inuktitut) is mapped to + ike (Eastern Canadian Inuktitut) and iu (Inuktitut) but not to + ikt (Inuinnaqtun, which is an individual language of iu), so + this method does not add a mapping from ikt to INUK. + + If a BCP 47 tag for a macrolanguage has no OpenType mapping but + some of its individual languages do, their mappings are copied + to the macrolanguage. + """ + global bcp_47 + first_time = self.from_bcp_47_uninherited is None + if first_time: + self.from_bcp_47_uninherited = dict (self.from_bcp_47) + for macrolanguage, languages in dict (bcp_47.macrolanguages).items (): + ot_macrolanguages = { + ot_macrolanguage for ot_macrolanguage in self.from_bcp_47_uninherited.get (macrolanguage, set ()) + } + blocked_ot_macrolanguages = set () + if 'retired code' not in bcp_47.scopes.get (macrolanguage, ''): + for ot_macrolanguage in ot_macrolanguages: + round_trip_macrolanguages = { + l for l in self.to_bcp_47[ot_macrolanguage] + if 'retired code' not in bcp_47.scopes.get (l, '') + } + round_trip_languages = { + l for l in languages + if 'retired code' not in bcp_47.scopes.get (l, '') + } + intersection = round_trip_macrolanguages & round_trip_languages + if intersection and intersection != round_trip_languages: + blocked_ot_macrolanguages.add (ot_macrolanguage) + if ot_macrolanguages: + for ot_macrolanguage in ot_macrolanguages: + if ot_macrolanguage not in blocked_ot_macrolanguages: + for language in languages: + self.add_language (language, ot_macrolanguage) + if not blocked_ot_macrolanguages: + self.ranks[ot_macrolanguage] += 1 + elif first_time: + for language in languages: + if language in self.from_bcp_47_uninherited: + ot_macrolanguages |= self.from_bcp_47_uninherited[language] + else: + ot_macrolanguages.clear () + if not ot_macrolanguages: + break + for ot_macrolanguage in ot_macrolanguages: + self.add_language (macrolanguage, ot_macrolanguage) + + def sort_languages (self): + """Sort the values of ``from_bcp_47`` in ascending rank order.""" + for language, tags in self.from_bcp_47.items (): + self.from_bcp_47[language] = sorted (tags, + key=lambda t: (self.ranks[t] + rank_delta (language, t), t)) + +ot = OpenTypeRegistryParser () + +class BCP47Parser (object): + """A parser for the BCP 47 subtag registry. + + Attributes: + header (str): The "File-Date" line of the registry. + names (Mapping[str, str]): A map of subtags to the names they + are given in the registry. Each value is a + ``'\\n'``-separated list of names. + scopes (Mapping[str, str]): A map of language subtags to strings + suffixed to language names, including suffixes to explain + language scopes. + macrolanguages (DefaultDict[str, AbstractSet[str]]): A map of + language subtags to the sets of language subtags which + inherit from them. See + ``OpenTypeRegistryParser.inherit_from_macrolanguages``. + prefixes (DefaultDict[str, AbstractSet[str]]): A map of variant + subtags to their prefixes. + grandfathered (AbstractSet[str]): The set of grandfathered tags, + normalized to lowercase. + + """ + def __init__ (self): + self.header = '' + self.names = {} + self.scopes = {} + self.macrolanguages = collections.defaultdict (set) + self.prefixes = collections.defaultdict (set) + self.grandfathered = set () + + def parse (self, filename): + """Parse the BCP 47 subtag registry. + + Args: + filename (str): The file name of the registry. + """ + with open (filename, encoding='utf-8') as f: + subtag_type = None + subtag = None + deprecated = False + has_preferred_value = False + line_buffer = '' + for line in itertools.chain (f, ['']): + line = line.rstrip () + if line.startswith (' '): + line_buffer += line[1:] + continue + line, line_buffer = line_buffer, line + if line.startswith ('Type: '): + subtag_type = line.split (' ')[1] + deprecated = False + has_preferred_value = False + elif line.startswith ('Subtag: ') or line.startswith ('Tag: '): + subtag = line.split (' ')[1] + if subtag_type == 'grandfathered': + self.grandfathered.add (subtag.lower ()) + elif line.startswith ('Description: '): + description = line.split (' ', 1)[1].replace (' (individual language)', '') + description = re.sub (' (\(family\)|\((individual |macro)language\)|languages)$', '', + description) + if subtag in self.names: + self.names[subtag] += '\n' + description + else: + self.names[subtag] = description + elif subtag_type == 'language' or subtag_type == 'grandfathered': + if line.startswith ('Scope: '): + scope = line.split (' ')[1] + if scope == 'macrolanguage': + scope = ' [macrolanguage]' + elif scope == 'collection': + scope = ' [collection]' + else: + continue + self.scopes[subtag] = scope + elif line.startswith ('Deprecated: '): + self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') + deprecated = True + elif deprecated and line.startswith ('Comments: see '): + # If a subtag is split into multiple replacement subtags, + # it essentially represents a macrolanguage. + for language in line.replace (',', '').split (' ')[2:]: + self._add_macrolanguage (subtag, language) + elif line.startswith ('Preferred-Value: '): + # If a subtag is deprecated in favor of a single replacement subtag, + # it is either a dialect or synonym of the preferred subtag. Either + # way, it is close enough to the truth to consider the replacement + # the macrolanguage of the deprecated language. + has_preferred_value = True + macrolanguage = line.split (' ')[1] + self._add_macrolanguage (macrolanguage, subtag) + elif not has_preferred_value and line.startswith ('Macrolanguage: '): + self._add_macrolanguage (line.split (' ')[1], subtag) + elif subtag_type == 'variant': + if line.startswith ('Deprecated: '): + self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') + elif line.startswith ('Prefix: '): + self.prefixes[subtag].add (line.split (' ')[1]) + elif line.startswith ('File-Date: '): + self.header = line + expect (self.header) + + def _add_macrolanguage (self, macrolanguage, language): + global ot + if language not in ot.from_bcp_47: + for l in self.macrolanguages.get (language, set ()): + self._add_macrolanguage (macrolanguage, l) + if macrolanguage not in ot.from_bcp_47: + for ls in list (self.macrolanguages.values ()): + if macrolanguage in ls: + ls.add (language) + return + self.macrolanguages[macrolanguage].add (language) + + def remove_extra_macrolanguages (self): + """Make every language have at most one macrolanguage.""" + inverted = collections.defaultdict (list) + for macrolanguage, languages in self.macrolanguages.items (): + for language in languages: + inverted[language].append (macrolanguage) + for language, macrolanguages in inverted.items (): + if len (macrolanguages) > 1: + macrolanguages.sort (key=lambda ml: len (self.macrolanguages[ml])) + biggest_macrolanguage = macrolanguages.pop () + for macrolanguage in macrolanguages: + self._add_macrolanguage (biggest_macrolanguage, macrolanguage) + + def _get_name_piece (self, subtag): + """Return the first name of a subtag plus its scope suffix. + + Args: + subtag (str): A BCP 47 subtag. + + Returns: + The name form of ``subtag``. + """ + return self.names[subtag].split ('\n')[0] + self.scopes.get (subtag, '') + + def get_name (self, lt): + """Return the names of the subtags in a language tag. + + Args: + lt (LanguageTag): A BCP 47 language tag. + + Returns: + The name form of ``lt``. + """ + name = self._get_name_piece (lt.language) + if lt.script: + name += '; ' + self._get_name_piece (lt.script.title ()) + if lt.region: + name += '; ' + self._get_name_piece (lt.region.upper ()) + if lt.variant: + name += '; ' + self._get_name_piece (lt.variant) + return name + +bcp_47 = BCP47Parser () + +ot.parse (sys.argv[1]) +bcp_47.parse (sys.argv[2]) + +ot.add_language ('ary', 'MOR') + +ot.add_language ('ath', 'ATH') + +ot.add_language ('bai', 'BML') + +ot.ranks['BAL'] = ot.ranks['KAR'] + 1 + +ot.add_language ('ber', 'BBR') + +ot.remove_language_ot ('PGR') +ot.add_language ('el-polyton', 'PGR') + +bcp_47.macrolanguages['et'] = {'ekk'} + +bcp_47.names['flm'] = 'Falam Chin' +bcp_47.scopes['flm'] = ' (retired code)' +bcp_47.macrolanguages['flm'] = {'cfm'} + +ot.ranks['FNE'] = ot.ranks['TNE'] + 1 + +ot.add_language ('und-fonipa', 'IPPH') + +ot.add_language ('und-fonnapa', 'APPH') + +ot.remove_language_ot ('IRT') +ot.add_language ('ga-Latg', 'IRT') + +ot.add_language ('hy-arevmda', 'HYE') + +ot.remove_language_ot ('KGE') +ot.add_language ('und-Geok', 'KGE') + +bcp_47.macrolanguages['id'] = {'in'} + +bcp_47.macrolanguages['ijo'] = {'ijc'} + +ot.add_language ('kht', 'KHN') +ot.names['KHN'] = ot.names['KHT'] + ' (Microsoft fonts)' +ot.ranks['KHN'] = ot.ranks['KHT'] + 1 + +ot.ranks['LCR'] = ot.ranks['MCR'] + 1 + +ot.names['MAL'] = 'Malayalam Traditional' +ot.ranks['MLR'] += 1 + +bcp_47.names['mhv'] = 'Arakanese' +bcp_47.scopes['mhv'] = ' (retired code)' + +ot.add_language ('mnw-TH', 'MONT') + +ot.add_language ('no', 'NOR') + +ot.add_language ('oc-provenc', 'PRO') + +ot.remove_language_ot ('QUZ') +ot.add_language ('qu', 'QUZ') +ot.add_language ('qub', 'QWH') +ot.add_language ('qud', 'QVI') +ot.add_language ('qug', 'QVI') +ot.add_language ('qul', 'QUH') +ot.add_language ('qup', 'QVI') +ot.add_language ('qur', 'QWH') +ot.add_language ('qus', 'QUH') +ot.add_language ('quw', 'QVI') +ot.add_language ('qux', 'QWH') +ot.add_language ('qva', 'QWH') +ot.add_language ('qvh', 'QWH') +ot.add_language ('qvj', 'QVI') +ot.add_language ('qvl', 'QWH') +ot.add_language ('qvm', 'QWH') +ot.add_language ('qvn', 'QWH') +ot.add_language ('qvo', 'QVI') +ot.add_language ('qvp', 'QWH') +ot.add_language ('qvw', 'QWH') +ot.add_language ('qvz', 'QVI') +ot.add_language ('qwa', 'QWH') +ot.add_language ('qws', 'QWH') +ot.add_language ('qxa', 'QWH') +ot.add_language ('qxc', 'QWH') +ot.add_language ('qxh', 'QWH') +ot.add_language ('qxl', 'QVI') +ot.add_language ('qxn', 'QWH') +ot.add_language ('qxo', 'QWH') +ot.add_language ('qxr', 'QVI') +ot.add_language ('qxt', 'QWH') +ot.add_language ('qxw', 'QWH') + +bcp_47.macrolanguages['ro-MD'].add ('mo') + +ot.remove_language_ot ('SYRE') +ot.remove_language_ot ('SYRJ') +ot.remove_language_ot ('SYRN') +ot.add_language ('und-Syre', 'SYRE') +ot.add_language ('und-Syrj', 'SYRJ') +ot.add_language ('und-Syrn', 'SYRN') + +bcp_47.names['xst'] = "Silt'e" +bcp_47.scopes['xst'] = ' (retired code)' +bcp_47.macrolanguages['xst'] = {'stv', 'wle'} + +ot.add_language ('xwo', 'TOD') + +ot.remove_language_ot ('ZHH') +ot.remove_language_ot ('ZHP') +ot.remove_language_ot ('ZHT') +ot.remove_language_ot ('ZHTM') +bcp_47.macrolanguages['zh'].remove ('lzh') +bcp_47.macrolanguages['zh'].remove ('yue') +ot.add_language ('zh-Hant-MO', 'ZHH') +ot.add_language ('zh-Hant-MO', 'ZHTM') +ot.add_language ('zh-Hant-HK', 'ZHH') +ot.add_language ('zh-Hans', 'ZHS') +ot.add_language ('zh-Hant', 'ZHT') +ot.add_language ('zh-HK', 'ZHH') +ot.add_language ('zh-MO', 'ZHH') +ot.add_language ('zh-MO', 'ZHTM') +ot.add_language ('zh-TW', 'ZHT') +ot.add_language ('lzh', 'ZHT') +ot.add_language ('lzh-Hans', 'ZHS') +ot.add_language ('yue', 'ZHH') +ot.add_language ('yue-Hans', 'ZHS') + +bcp_47.macrolanguages['zom'] = {'yos'} + +def rank_delta (bcp_47, ot): + """Return a delta to apply to a BCP 47 tag's rank. + + Most OpenType tags have a constant rank, but a few have ranks that + depend on the BCP 47 tag. + + Args: + bcp_47 (str): A BCP 47 tag. + ot (str): An OpenType tag to. + + Returns: + A number to add to ``ot``'s rank when sorting ``bcp_47``'s + OpenType equivalents. + """ + if bcp_47 == 'ak' and ot == 'AKA': + return -1 + if bcp_47 == 'tw' and ot == 'TWI': + return -1 + return 0 + +disambiguation = { + 'ALT': 'alt', + 'ARK': 'rki', + 'ATH': 'ath', + 'BHI': 'bhb', + 'BLN': 'bjt', + 'BTI': 'beb', + 'CCHN': 'cco', + 'CMR': 'swb', + 'CPP': 'crp', + 'CRR': 'crx', + 'DUJ': 'dwu', + 'ECR': 'crj', + 'HAL': 'cfm', + 'HND': 'hnd', + 'HYE': 'hyw', + 'KIS': 'kqs', + 'KUI': 'uki', + 'LRC': 'bqi', + 'NDB': 'nd', + 'NIS': 'njz', + 'PLG': 'pce', + 'PRO': 'pro', + 'QIN': 'bgr', + 'QUH': 'quh', + 'QVI': 'qvi', + 'QWH': 'qwh', + 'SIG': 'stv', + 'SRB': 'sr', + 'SXT': 'xnj', + 'ZHH': 'zh-HK', + 'ZHS': 'zh-Hans', + 'ZHT': 'zh-Hant', + 'ZHTM': 'zh-MO', +} + +ot.inherit_from_macrolanguages () +bcp_47.remove_extra_macrolanguages () +ot.inherit_from_macrolanguages () +ot.names[DEFAULT_LANGUAGE_SYSTEM] = '*/' +ot.ranks[DEFAULT_LANGUAGE_SYSTEM] = max (ot.ranks.values ()) + 1 +for tricky_ot_tag in filter (lambda tag: re.match ('[A-Z]{3}$', tag), ot.names): + possible_bcp_47_tag = tricky_ot_tag.lower () + if possible_bcp_47_tag in bcp_47.names and not ot.from_bcp_47[possible_bcp_47_tag]: + ot.add_language (possible_bcp_47_tag, DEFAULT_LANGUAGE_SYSTEM) + bcp_47.macrolanguages[possible_bcp_47_tag] = set () +ot.sort_languages () + +print ('/* == Start of generated table == */') +print ('/*') +print (' * The following table is generated by running:') +print (' *') +print (' * %s languagetags language-subtag-registry' % sys.argv[0]) +print (' *') +print (' * on files with these headers:') +print (' *') +print (' * %s' % ot.header.strip ()) +print (' * %s' % bcp_47.header) +print (' */') +print () +print ('#ifndef HB_OT_TAG_TABLE_HH') +print ('#define HB_OT_TAG_TABLE_HH') +print () + +def hb_tag (tag): + """Convert a tag to ``HB_TAG`` form. + + Args: + tag (str): An OpenType tag. + + Returns: + A snippet of C++ representing ``tag``. + """ + if tag == DEFAULT_LANGUAGE_SYSTEM: + return 'HB_TAG_NONE\t ' + return "HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4]) + +def get_variant_set (name): + """Return a set of variant language names from a name. + + Args: + name (str): A list of language names from the BCP 47 registry, + joined on ``'\\n'``. + + Returns: + A set of normalized language names. + """ + return set (unicodedata.normalize ('NFD', n.replace ('\u2019', "'")) + .encode ('ASCII', 'ignore') + .strip () + for n in re.split ('[\n(),]', name) if n) + +def language_name_intersection (a, b): + """Return the names in common between two language names. + + Args: + a (str): A list of language names from the BCP 47 registry, + joined on ``'\\n'``. + b (str): A list of language names from the BCP 47 registry, + joined on ``'\\n'``. + + Returns: + The normalized language names shared by ``a`` and ``b``. + """ + return get_variant_set (a).intersection (get_variant_set (b)) + +def get_matching_language_name (intersection, candidates): + return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) + +def same_tag (bcp_47_tag, ot_tags): + return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower () + +for language_len in (2, 3): + if language_len == 3: + print ('#ifndef HB_NO_LANGUAGE_LONG') + print ('static const LangTag ot_languages%d[] = {' % language_len) + for language, tags in sorted (ot.from_bcp_47.items ()): + if language == '' or '-' in language: + continue + if len(language) != language_len: continue + commented_out = same_tag (language, tags) + for i, tag in enumerate (tags, start=1): + print ('%s{%s,\t%s},' % ('/*' if commented_out else ' ', hb_tag (language), hb_tag (tag)), end='') + if commented_out: + print ('*/', end='') + print ('\t/* ', end='') + bcp_47_name = bcp_47.names.get (language, '') + bcp_47_name_candidates = bcp_47_name.split ('\n') + ot_name = ot.names[tag] + scope = bcp_47.scopes.get (language, '') + if tag == DEFAULT_LANGUAGE_SYSTEM: + write (f'{bcp_47_name_candidates[0]}{scope} != {ot.names[language.upper ()]}') + else: + intersection = language_name_intersection (bcp_47_name, ot_name) + if not intersection: + write ('%s%s -> %s' % (bcp_47_name_candidates[0], scope, ot_name)) + else: + name = get_matching_language_name (intersection, bcp_47_name_candidates) + bcp_47.names[language] = name + write ('%s%s' % (name if len (name) > len (ot_name) else ot_name, scope)) + print (' */') + print ('};') + if language_len == 3: + print ('#endif') + print () + +print ('/**') +print (' * hb_ot_tags_from_complex_language:') +print (' * @lang_str: a BCP 47 language tag to convert.') +print (' * @limit: a pointer to the end of the substring of @lang_str to consider for') +print (' * conversion.') +print (' * @count: maximum number of language tags to retrieve (IN) and actual number of') +print (' * language tags retrieved (OUT). If no tags are retrieved, it is not modified.') +print (' * @tags: array of size at least @language_count to store the language tag') +print (' * results') +print (' *') +print (' * Converts a multi-subtag BCP 47 language tag to language tags.') +print (' *') +print (' * Return value: Whether any language systems were retrieved.') +print (' **/') +print ('static inline bool') +print ('hb_ot_tags_from_complex_language (const char *lang_str,') +print ('\t\t\t\t const char *limit,') +print ('\t\t\t\t unsigned int *count /* IN/OUT */,') +print ('\t\t\t\t hb_tag_t *tags /* OUT */)') +print ('{') + +def print_subtag_matches (subtag, string, new_line): + if subtag: + if new_line: + print () + print ('\t&& ', end='') + print ('subtag_matches (%s, limit, "-%s", %i)' % (string, subtag, 1 + len (subtag)), end='') + +complex_tags = collections.defaultdict (list) +for initial, group in itertools.groupby ((lt_tags for lt_tags in [ + (LanguageTag (language), tags) + for language, tags in sorted (ot.from_bcp_47.items (), + key=lambda i: (-len (i[0]), i[0])) + ] if lt_tags[0].is_complex ()), + key=lambda lt_tags: lt_tags[0].get_group ()): + complex_tags[initial] += group + +# Calculate the min length of the subtags outside the switch +min_subtag_len = 100 +for initial, items in sorted (complex_tags.items ()): + if initial != 'und': + continue + for lt, tags in items: + if not tags: + continue + subtag_len = 0 + subtag_len += 1 + len (lt.script) if lt.script is not None else 0 + subtag_len += 1 + len (lt.region) if lt.region is not None else 0 + subtag_len += 1 + len (lt.variant) if lt.variant is not None else 0 + min_subtag_len = min(subtag_len, min_subtag_len) + +print (' if (limit - lang_str >= %d)' % (min_subtag_len + 2)) +print (' {') +print (" const char *p = strchr (lang_str, '-');") +print (" if (!p || p >= limit || limit - p < %i) goto out;" % min_subtag_len) +for initial, items in sorted (complex_tags.items ()): + if initial != 'und': + continue + for lt, tags in items: + if not tags: + continue + if lt.variant in bcp_47.prefixes: + expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language, + '%s is not a valid prefix of %s' % (lt.language, lt.variant)) + print (' if (', end='') + print_subtag_matches (lt.script, 'p', False) + print_subtag_matches (lt.region, 'p', False) + print_subtag_matches (lt.variant, 'p', False) + print (')') + print (' {') + write (' /* %s */' % bcp_47.get_name (lt)) + print () + if len (tags) == 1: + write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) + print () + print (' *count = 1;') + else: + print (' hb_tag_t possible_tags[] = {') + for tag in tags: + write (' %s, /* %s */' % (hb_tag (tag), ot.names[tag])) + print () + print (' };') + print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) + print ('\ttags[i] = possible_tags[i];') + print (' *count = i;') + print (' return true;') + print (' }') +print (' }') +print ('out:') + +print (' switch (lang_str[0])') +print (' {') +for initial, items in sorted (complex_tags.items ()): + if initial == 'und': + continue + print (" case '%s':" % initial) + for lt, tags in items: + if not tags: + continue + print (' if (', end='') + script = lt.script + region = lt.region + if lt.grandfathered: + print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='') + else: + string_literal = lt.language[1:] + '-' + if script: + string_literal += script + script = None + if region: + string_literal += '-' + region + region = None + if string_literal[-1] == '-': + print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='') + else: + print ('lang_matches (&lang_str[1], limit, "%s", %i)' % (string_literal, len (string_literal)), end='') + print_subtag_matches (script, 'lang_str', True) + print_subtag_matches (region, 'lang_str', True) + print_subtag_matches (lt.variant, 'lang_str', True) + print (')') + print (' {') + write (' /* %s */' % bcp_47.get_name (lt)) + print () + if len (tags) == 1: + write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) + print () + print (' *count = 1;') + else: + print (' unsigned int i;') + print (' hb_tag_t possible_tags[] = {') + for tag in tags: + write ('\t%s, /* %s */' % (hb_tag (tag), ot.names[tag])) + print () + print (' };') + print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) + print ('\ttags[i] = possible_tags[i];') + print (' *count = i;') + print (' return true;') + print (' }') + print (' break;') + +print (' }') +print (' return false;') +print ('}') +print () +print ('/**') +print (' * hb_ot_ambiguous_tag_to_language') +print (' * @tag: A language tag.') +print (' *') +print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to') +print (' * many language tags) and the best tag is not the alphabetically first, or if') +print (' * the best tag consists of multiple subtags, or if the best tag does not appear') +print (' * in #ot_languages.') +print (' *') +print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') +print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') +print (' **/') +print ('static inline hb_language_t') +print ('hb_ot_ambiguous_tag_to_language (hb_tag_t tag)') +print ('{') +print (' switch (tag)') +print (' {') + +def verify_disambiguation_dict (): + """Verify and normalize ``disambiguation``. + + ``disambiguation`` is a map of ambiguous OpenType language system + tags to the particular BCP 47 tags they correspond to. This function + checks that all its keys really are ambiguous and that each key's + value is valid for that key. It checks that no ambiguous tag is + missing, except when it can figure out which BCP 47 tag is the best + by itself. + + It modifies ``disambiguation`` to remove keys whose values are the + same as those that the fallback would return anyway, and to add + ambiguous keys whose disambiguations it determined automatically. + + Raises: + AssertionError: Verification failed. + """ + global bcp_47 + global disambiguation + global ot + for ot_tag, bcp_47_tags in ot.to_bcp_47.items (): + if ot_tag == DEFAULT_LANGUAGE_SYSTEM: + primary_tags = [] + else: + primary_tags = list (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot.from_bcp_47.get (t)[0] == ot_tag) + if len (primary_tags) == 1: + expect (ot_tag not in disambiguation, 'unnecessary disambiguation for OT tag: %s' % ot_tag) + if '-' in primary_tags[0]: + disambiguation[ot_tag] = primary_tags[0] + else: + first_tag = sorted (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot_tag in ot.from_bcp_47.get (t))[0] + if primary_tags[0] != first_tag: + disambiguation[ot_tag] = primary_tags[0] + elif len (primary_tags) == 0: + expect (ot_tag not in disambiguation, 'There is no possible valid disambiguation for %s' % ot_tag) + else: + original_languages = [t for t in primary_tags if t in ot.from_bcp_47_uninherited and 'retired code' not in bcp_47.scopes.get (t, '')] + if len (original_languages) == 1: + macrolanguages = original_languages + else: + macrolanguages = [t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]'] + if len (macrolanguages) != 1: + macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [collection]') + if len (macrolanguages) != 1: + macrolanguages = list (t for t in primary_tags if 'retired code' not in bcp_47.scopes.get (t, '')) + if len (macrolanguages) != 1: + expect (ot_tag in disambiguation, 'ambiguous OT tag: %s %s' % (ot_tag, str (macrolanguages))) + expect (disambiguation[ot_tag] in bcp_47_tags, + '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) + elif ot_tag not in disambiguation: + disambiguation[ot_tag] = macrolanguages[0] + different_bcp_47_tags = sorted (t for t in bcp_47_tags if not same_tag (t, ot.from_bcp_47.get (t))) + if different_bcp_47_tags and disambiguation[ot_tag] == different_bcp_47_tags[0] and '-' not in disambiguation[ot_tag]: + del disambiguation[ot_tag] + for ot_tag in disambiguation.keys (): + expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) + +verify_disambiguation_dict () +for ot_tag, bcp_47_tag in sorted (disambiguation.items ()): + write (' case %s: /* %s */' % (hb_tag (ot_tag), ot.names[ot_tag])) + print () + write (' return hb_language_from_string (\"%s\", -1); /* %s */' % (bcp_47_tag, bcp_47.get_name (LanguageTag (bcp_47_tag)))) + print () + +print (' default:') +print (' return HB_LANGUAGE_INVALID;') +print (' }') +print ('}') + +print () +print ('#endif /* HB_OT_TAG_TABLE_HH */') +print () +print ('/* == End of generated table == */') + diff --git a/gfx/harfbuzz/src/gen-ucd-table.py b/gfx/harfbuzz/src/gen-ucd-table.py index e5be65a6f1..bb53dcd1dd 100644 --- a/gfx/harfbuzz/src/gen-ucd-table.py +++ b/gfx/harfbuzz/src/gen-ucd-table.py @@ -1,202 +1,203 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h] - -Input file: -* https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip -""" - -import sys, re -import logging -logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) - -if len (sys.argv) not in (2, 3): - sys.exit (__doc__) - -# https://github.com/harfbuzz/packtab -import packTab -import packTab.ucdxml - -logging.info('Loading UCDXML...') -ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1]) -ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml) - -hb_common_h = 'hb-common.h' if len (sys.argv) < 3 else sys.argv[2] - -logging.info('Preparing data tables...') - - -# This is how the data is encoded: -# -# General_Category (gc), Canonical_Combining_Class (ccc), -# and Script (sc) are encoded as integers. -# -# Mirroring character (bmg) is encoded as difference from -# the original character. -# -# Composition & Decomposition (dm) are encoded elaborately, -# as discussed below. - -gc = [u['gc'] for u in ucd] -ccc = [int(u['ccc']) for u in ucd] -bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)] -sc = [u['sc'] for u in ucd] - - -# Prepare Compose / Decompose data -# -# This code is very dense. See hb_ucd_compose() / hb_ucd_decompose() for the logic. - -dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd) - if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)} -ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'} - -assert not any(v for v in dm.values() if len(v) not in (1,2)) -dm1 = sorted(set(v for v in dm.values() if len(v) == 1)) -assert all((v[0] >> 16) in (0,2) for v in dm1) -dm1_p0_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0] -dm1_p2_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2] -dm1_order = {v:i+1 for i,v in enumerate(dm1)} - -dm2 = sorted((v+(i if i not in ce and not ccc[i] else 0,), v) - for i,v in dm.items() if len(v) == 2) - -filt = lambda v: ((v[0] & 0xFFFFF800) == 0x0000 and - (v[1] & 0xFFFFFF80) == 0x0300 and - (v[2] & 0xFFF0C000) == 0x0000) -dm2_u32_array = [v for v in dm2 if filt(v[0])] -dm2_u64_array = [v for v in dm2 if not filt(v[0])] -assert dm2_u32_array + dm2_u64_array == dm2 -dm2_u32_array = ["HB_CODEPOINT_ENCODE3_11_7_14 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u32_array] -dm2_u64_array = ["HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u64_array] - -l = 1 + len(dm1_p0_array) + len(dm1_p2_array) -dm2_order = {v[1]:i+l for i,v in enumerate(dm2)} - -dm_order = {None: 0} -dm_order.update(dm1_order) -dm_order.update(dm2_order) - - -# Prepare General_Category / Script mapping arrays - -gc_order = dict() -for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', - 'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', - 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',)): - gc_order[i] = v - gc_order[v] = i - -sc_order = dict() -sc_array = [] -sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]") -for line in open(hb_common_h): - m = sc_re.search (line) - if not m: continue - name = m.group(1) - tag = ''.join(m.group(i) for i in range(2, 6)) - i = len(sc_array) - sc_order[tag] = i - sc_order[i] = tag - sc_array.append(name) - - -# Write out main data - -DEFAULT = 'DEFAULT' -COMPACT = 'COMPACT' -SLOPPY = 'SLOPPY' - -compression_level = { - DEFAULT: 5, - COMPACT: 9, - SLOPPY: 9, -} - -logging.info('Generating output...') -print("/* == Start of generated table == */") -print("/*") -print(" * The following table is generated by running:") -print(" *") -print(" * ./gen-ucd-table.py ucd.nounihan.grouped.xml") -print(" *") -print(" * on file with this description:", ucdxml.description) -print(" */") -print() -print("#ifndef HB_UCD_TABLE_HH") -print("#define HB_UCD_TABLE_HH") -print() -print('#include "hb.hh"') -print() - - -# Write mapping data - -code = packTab.Code('_hb_ucd') -sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array) -dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array) -dm1_p2_array, _ = code.addArray('uint16_t', 'dm1_p2_map', dm1_p2_array) -dm2_u32_array, _ = code.addArray('uint32_t', 'dm2_u32_map', dm2_u32_array) -dm2_u64_array, _ = code.addArray('uint64_t', 'dm2_u64_map', dm2_u64_array) -code.print_c(linkage='static inline') - -datasets = [ - ('gc', gc, 'Cn', gc_order), - ('ccc', ccc, 0, None), - ('bmg', bmg, 0, None), - ('sc', sc, 'Zzzz', sc_order), - ('dm', dm, None, dm_order), -] - - -# Write main data - -for step in (DEFAULT, COMPACT, SLOPPY): - compression = compression_level[step] - logging.info(' Compression=%d:' % compression) - print() - if step == DEFAULT: - print('#ifndef HB_OPTIMIZE_SIZE') - elif step == COMPACT: - print('#elif !defined(HB_NO_UCD_UNASSIGNED)') - elif step == SLOPPY: - print('#else') - else: - assert False - print() - - if step == SLOPPY: - for i in range(len(gc)): - if (i % 128) and gc[i] == 'Cn': - gc[i] = gc[i - 1] - for i in range(len(gc) - 2, -1, -1): - if ((i + 1) % 128) and gc[i] == 'Cn': - gc[i] = gc[i + 1] - for i in range(len(sc)): - if (i % 128) and sc[i] == 'Zzzz': - sc[i] = sc[i - 1] - for i in range(len(sc) - 2, -1, -1): - if ((i + 1) % 128) and sc[i] == 'Zzzz': - sc[i] = sc[i + 1] - - - code = packTab.Code('_hb_ucd') - - for name,data,default,mapping in datasets: - sol = packTab.pack_table(data, default, mapping=mapping, compression=compression) - logging.info(' Dataset=%-8s FullCost=%d' % (name, sol.fullCost)) - sol.genCode(code, name) - - code.print_c(linkage='static inline') - - print() - - -print('#endif') -print() - -print() -print("#endif /* HB_UCD_TABLE_HH */") -print() -print("/* == End of generated table == */") -logging.info('Done.') +#!/usr/bin/env python3 + +"""usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h] + +Input file: +* https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip +""" + +from __future__ import print_function +import sys, re +import logging +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) + +if len (sys.argv) not in (2, 3): + sys.exit (__doc__) + +# https://github.com/harfbuzz/packtab +import packTab +import packTab.ucdxml + +logging.info('Loading UCDXML...') +ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1]) +ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml) + +hb_common_h = 'hb-common.h' if len (sys.argv) < 3 else sys.argv[2] + +logging.info('Preparing data tables...') + + +# This is how the data is encoded: +# +# General_Category (gc), Canonical_Combining_Class (ccc), +# and Script (sc) are encoded as integers. +# +# Mirroring character (bmg) is encoded as difference from +# the original character. +# +# Composition & Decomposition (dm) are encoded elaborately, +# as discussed below. + +gc = [u['gc'] for u in ucd] +ccc = [int(u['ccc']) for u in ucd] +bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)] +sc = [u['sc'] for u in ucd] + + +# Prepare Compose / Decompose data +# +# This code is very dense. See hb_ucd_compose() / hb_ucd_decompose() for the logic. + +dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd) + if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)} +ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'} + +assert not any(v for v in dm.values() if len(v) not in (1,2)) +dm1 = sorted(set(v for v in dm.values() if len(v) == 1)) +assert all((v[0] >> 16) in (0,2) for v in dm1) +dm1_p0_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0] +dm1_p2_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2] +dm1_order = {v:i+1 for i,v in enumerate(dm1)} + +dm2 = sorted((v+(i if i not in ce and not ccc[i] else 0,), v) + for i,v in dm.items() if len(v) == 2) + +filt = lambda v: ((v[0] & 0xFFFFF800) == 0x0000 and + (v[1] & 0xFFFFFF80) == 0x0300 and + (v[2] & 0xFFF0C000) == 0x0000) +dm2_u32_array = [v for v in dm2 if filt(v[0])] +dm2_u64_array = [v for v in dm2 if not filt(v[0])] +assert dm2_u32_array + dm2_u64_array == dm2 +dm2_u32_array = ["HB_CODEPOINT_ENCODE3_11_7_14 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u32_array] +dm2_u64_array = ["HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u64_array] + +l = 1 + len(dm1_p0_array) + len(dm1_p2_array) +dm2_order = {v[1]:i+l for i,v in enumerate(dm2)} + +dm_order = {None: 0} +dm_order.update(dm1_order) +dm_order.update(dm2_order) + + +# Prepare General_Category / Script mapping arrays + +gc_order = dict() +for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', + 'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', + 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',)): + gc_order[i] = v + gc_order[v] = i + +sc_order = dict() +sc_array = [] +sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]") +for line in open(hb_common_h): + m = sc_re.search (line) + if not m: continue + name = m.group(1) + tag = ''.join(m.group(i) for i in range(2, 6)) + i = len(sc_array) + sc_order[tag] = i + sc_order[i] = tag + sc_array.append(name) + + +# Write out main data + +DEFAULT = 'DEFAULT' +COMPACT = 'COMPACT' +SLOPPY = 'SLOPPY' + +compression_level = { + DEFAULT: 5, + COMPACT: 9, + SLOPPY: 9, +} + +logging.info('Generating output...') +print("/* == Start of generated table == */") +print("/*") +print(" * The following table is generated by running:") +print(" *") +print(" * ./gen-ucd-table.py ucd.nounihan.grouped.xml") +print(" *") +print((" * on file with this description:", ucdxml.description)) +print(" */") +print() +print("#ifndef HB_UCD_TABLE_HH") +print("#define HB_UCD_TABLE_HH") +print() +print('#include "hb.hh"') +print() + + +# Write mapping data + +code = packTab.Code('_hb_ucd') +sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array) +dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array) +dm1_p2_array, _ = code.addArray('uint16_t', 'dm1_p2_map', dm1_p2_array) +dm2_u32_array, _ = code.addArray('uint32_t', 'dm2_u32_map', dm2_u32_array) +dm2_u64_array, _ = code.addArray('uint64_t', 'dm2_u64_map', dm2_u64_array) +code.print_c(linkage='static inline') + +datasets = [ + ('gc', gc, 'Cn', gc_order), + ('ccc', ccc, 0, None), + ('bmg', bmg, 0, None), + ('sc', sc, 'Zzzz', sc_order), + ('dm', dm, None, dm_order), +] + + +# Write main data + +for step in (DEFAULT, COMPACT, SLOPPY): + compression = compression_level[step] + logging.info(' Compression=%d:' % compression) + print() + if step == DEFAULT: + print('#ifndef HB_OPTIMIZE_SIZE') + elif step == COMPACT: + print('#elif !defined(HB_NO_UCD_UNASSIGNED)') + elif step == SLOPPY: + print('#else') + else: + assert False + print() + + if step == SLOPPY: + for i in range(len(gc)): + if (i % 128) and gc[i] == 'Cn': + gc[i] = gc[i - 1] + for i in range(len(gc) - 2, -1, -1): + if ((i + 1) % 128) and gc[i] == 'Cn': + gc[i] = gc[i + 1] + for i in range(len(sc)): + if (i % 128) and sc[i] == 'Zzzz': + sc[i] = sc[i - 1] + for i in range(len(sc) - 2, -1, -1): + if ((i + 1) % 128) and sc[i] == 'Zzzz': + sc[i] = sc[i + 1] + + + code = packTab.Code('_hb_ucd') + + for name,data,default,mapping in datasets: + sol = packTab.pack_table(data, default, mapping=mapping, compression=compression) + logging.info(' Dataset=%-8s FullCost=%d' % (name, sol.fullCost)) + sol.genCode(code, name) + + code.print_c(linkage='static inline') + + print() + + +print('#endif') +print() + +print() +print("#endif /* HB_UCD_TABLE_HH */") +print() +print("/* == End of generated table == */") +logging.info('Done.') diff --git a/gfx/harfbuzz/src/gen-vowel-constraints.py b/gfx/harfbuzz/src/gen-vowel-constraints.py index 5bb5e9e8e8..299e612fd0 100644 --- a/gfx/harfbuzz/src/gen-vowel-constraints.py +++ b/gfx/harfbuzz/src/gen-vowel-constraints.py @@ -1,229 +1,230 @@ -#!/usr/bin/env python3 - -"""Generator of the function to prohibit certain vowel sequences. - -It creates ``_hb_preprocess_text_vowel_constraints``, which inserts dotted -circles into sequences prohibited by the USE script development spec. -This function should be used as the ``preprocess_text`` of an -``hb_ot_shaper_t``. - -usage: ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt - -Input file: -* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt -""" - -import collections -def write (s): - sys.stdout.flush () - sys.stdout.buffer.write (s.encode ('utf-8')) -import sys - -if len (sys.argv) != 3: - sys.exit (__doc__) - -with open (sys.argv[2], encoding='utf-8') as f: - scripts_header = [f.readline () for i in range (2)] - scripts = {} - script_order = {} - for line in f: - j = line.find ('#') - if j >= 0: - line = line[:j] - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - script = fields[1] - for u in range (start, end + 1): - scripts[u] = script - if script not in script_order: - script_order[script] = start - -class ConstraintSet (object): - """A set of prohibited code point sequences. - - Args: - constraint (List[int]): A prohibited code point sequence. - - """ - def __init__ (self, constraint): - # Either a list or a dictionary. As a list of code points, it - # represents a prohibited code point sequence. As a dictionary, - # it represents a set of prohibited sequences, where each item - # represents the set of prohibited sequences starting with the - # key (a code point) concatenated with any of the values - # (ConstraintSets). - self._c = constraint - - def add (self, constraint): - """Add a constraint to this set.""" - if not constraint: - return - first = constraint[0] - rest = constraint[1:] - if isinstance (self._c, list): - if constraint == self._c[:len (constraint)]: - self._c = constraint - elif self._c != constraint[:len (self._c)]: - self._c = {self._c[0]: ConstraintSet (self._c[1:])} - if isinstance (self._c, dict): - if first in self._c: - self._c[first].add (rest) - else: - self._c[first] = ConstraintSet (rest) - - @staticmethod - def _indent (depth): - return (' ' * depth).replace (' ', '\t') - - def __str__ (self, index=0, depth=4): - s = [] - indent = self._indent (depth) - if isinstance (self._c, list): - if len (self._c) == 0: - assert index == 2, 'Cannot use `matched` for this constraint; the general case has not been implemented' - s.append ('{}matched = true;\n'.format (indent)) - elif len (self._c) == 1: - assert index == 1, 'Cannot use `matched` for this constraint; the general case has not been implemented' - s.append ('{}matched = 0x{:04X}u == buffer->cur ({}).codepoint;\n'.format (indent, next (iter (self._c)), index or '')) - else: - s.append ('{}if (0x{:04X}u == buffer->cur ({}).codepoint &&\n'.format (indent, self._c[0], index or '')) - if index: - s.append ('{}buffer->idx + {} < count &&\n'.format (self._indent (depth + 2), index + 1)) - for i, cp in enumerate (self._c[1:], start=1): - s.append ('{}0x{:04X}u == buffer->cur ({}).codepoint{}\n'.format ( - self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&')) - s.append ('{}{{\n'.format (indent)) - for i in range (index): - s.append ('{}(void) buffer->next_glyph ();\n'.format (self._indent (depth + 1))) - s.append ('{}matched = true;\n'.format (self._indent (depth + 1))) - s.append ('{}}}\n'.format (indent)) - else: - s.append ('{}switch (buffer->cur ({}).codepoint)\n'.format(indent, index or '')) - s.append ('{}{{\n'.format (indent)) - cases = collections.defaultdict (set) - for first, rest in sorted (self._c.items ()): - cases[rest.__str__ (index + 1, depth + 2)].add (first) - for body, labels in sorted (cases.items (), key=lambda b_ls: sorted (b_ls[1])[0]): - for i, cp in enumerate (sorted (labels)): - if i % 4 == 0: - s.append (self._indent (depth + 1)) - else: - s.append (' ') - s.append ('case 0x{:04X}u:{}'.format (cp, '\n' if i % 4 == 3 else '')) - if len (labels) % 4 != 0: - s.append ('\n') - s.append (body) - s.append ('{}break;\n'.format (self._indent (depth + 2))) - s.append ('{}}}\n'.format (indent)) - return ''.join (s) - -constraints = {} -with open (sys.argv[1], encoding='utf-8') as f: - constraints_header = [] - while True: - line = f.readline ().strip () - if line == '#': - break - constraints_header.append(line) - for line in f: - j = line.find ('#') - if j >= 0: - line = line[:j] - constraint = [int (cp, 16) for cp in line.split (';')[0].split ()] - if not constraint: continue - assert 2 <= len (constraint), 'Prohibited sequence is too short: {}'.format (constraint) - script = scripts[constraint[0]] - if script in constraints: - constraints[script].add (constraint) - else: - constraints[script] = ConstraintSet (constraint) - assert constraints, 'No constraints found' - -print ('/* == Start of generated functions == */') -print ('/*') -print (' * The following functions are generated by running:') -print (' *') -print (' * %s ms-use/IndicShapingInvalidCluster.txt Scripts.txt' % sys.argv[0]) -print (' *') -print (' * on files with these headers:') -print (' *') -for line in constraints_header: - print (' * %s' % line.strip ()) -print (' *') -for line in scripts_header: - print (' * %s' % line.strip ()) -print (' */') - -print () -print ('#include "hb.hh"') -print () -print ('#ifndef HB_NO_OT_SHAPE') -print () -print ('#include "hb-ot-shaper-vowel-constraints.hh"') -print () -print ('static void') -print ('_output_dotted_circle (hb_buffer_t *buffer)') -print ('{') -print (' (void) buffer->output_glyph (0x25CCu);') -print (' _hb_glyph_info_reset_continuation (&buffer->prev());') -print ('}') -print () -print ('static void') -print ('_output_with_dotted_circle (hb_buffer_t *buffer)') -print ('{') -print (' _output_dotted_circle (buffer);') -print (' (void) buffer->next_glyph ();') -print ('}') -print () - -print ('void') -print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,') -print ('\t\t\t\t hb_buffer_t *buffer,') -print ('\t\t\t\t hb_font_t *font HB_UNUSED)') -print ('{') -print ('#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS') -print (' return;') -print ('#endif') -print (' if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)') -print (' return;') -print () -print (' /* UGLY UGLY UGLY business of adding dotted-circle in the middle of') -print (' * vowel-sequences that look like another vowel. Data for each script') -print (' * collected from the USE script development spec.') -print (' *') -print (' * https://github.com/harfbuzz/harfbuzz/issues/1019') -print (' */') -print (' buffer->clear_output ();') -print (' unsigned int count = buffer->len;') -print (' switch ((unsigned) buffer->props.script)') -print (' {') - -for script, constraints in sorted (constraints.items (), key=lambda s_c: script_order[s_c[0]]): - print (' case HB_SCRIPT_{}:'.format (script.upper ())) - print (' for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)') - print (' {') - print ('\tbool matched = false;') - write (str (constraints)) - print ('\t(void) buffer->next_glyph ();') - print ('\tif (matched) _output_with_dotted_circle (buffer);') - print (' }') - print (' break;') - print () - -print (' default:') -print (' break;') -print (' }') -print (' buffer->sync ();') -print ('}') - -print () -print () -print ('#endif') -print ('/* == End of generated functions == */') +#!/usr/bin/env python3 + +"""Generator of the function to prohibit certain vowel sequences. + +It creates ``_hb_preprocess_text_vowel_constraints``, which inserts dotted +circles into sequences prohibited by the USE script development spec. +This function should be used as the ``preprocess_text`` of an +``hb_ot_shaper_t``. + +usage: ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt + +Input file: +* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt +""" + +from __future__ import print_function +import collections +def write (s): + sys.stdout.flush () + sys.stdout.buffer.write (s.encode ('utf-8')) +import sys + +if len (sys.argv) != 3: + sys.exit (__doc__) + +with open (sys.argv[2], encoding='utf-8') as f: + scripts_header = [f.readline () for i in range (2)] + scripts = {} + script_order = {} + for line in f: + j = line.find ('#') + if j >= 0: + line = line[:j] + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + uu = fields[0].split ('..') + start = int (uu[0], 16) + if len (uu) == 1: + end = start + else: + end = int (uu[1], 16) + script = fields[1] + for u in range (start, end + 1): + scripts[u] = script + if script not in script_order: + script_order[script] = start + +class ConstraintSet (object): + """A set of prohibited code point sequences. + + Args: + constraint (List[int]): A prohibited code point sequence. + + """ + def __init__ (self, constraint): + # Either a list or a dictionary. As a list of code points, it + # represents a prohibited code point sequence. As a dictionary, + # it represents a set of prohibited sequences, where each item + # represents the set of prohibited sequences starting with the + # key (a code point) concatenated with any of the values + # (ConstraintSets). + self._c = constraint + + def add (self, constraint): + """Add a constraint to this set.""" + if not constraint: + return + first = constraint[0] + rest = constraint[1:] + if isinstance (self._c, list): + if constraint == self._c[:len (constraint)]: + self._c = constraint + elif self._c != constraint[:len (self._c)]: + self._c = {self._c[0]: ConstraintSet (self._c[1:])} + if isinstance (self._c, dict): + if first in self._c: + self._c[first].add (rest) + else: + self._c[first] = ConstraintSet (rest) + + @staticmethod + def _indent (depth): + return (' ' * depth).replace (' ', '\t') + + def __str__ (self, index=0, depth=4): + s = [] + indent = self._indent (depth) + if isinstance (self._c, list): + if len (self._c) == 0: + assert index == 2, 'Cannot use `matched` for this constraint; the general case has not been implemented' + s.append ('{}matched = true;\n'.format (indent)) + elif len (self._c) == 1: + assert index == 1, 'Cannot use `matched` for this constraint; the general case has not been implemented' + s.append ('{}matched = 0x{:04X}u == buffer->cur ({}).codepoint;\n'.format (indent, next (iter (self._c)), index or '')) + else: + s.append ('{}if (0x{:04X}u == buffer->cur ({}).codepoint &&\n'.format (indent, self._c[0], index or '')) + if index: + s.append ('{}buffer->idx + {} < count &&\n'.format (self._indent (depth + 2), index + 1)) + for i, cp in enumerate (self._c[1:], start=1): + s.append ('{}0x{:04X}u == buffer->cur ({}).codepoint{}\n'.format ( + self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&')) + s.append ('{}{{\n'.format (indent)) + for i in range (index): + s.append ('{}(void) buffer->next_glyph ();\n'.format (self._indent (depth + 1))) + s.append ('{}matched = true;\n'.format (self._indent (depth + 1))) + s.append ('{}}}\n'.format (indent)) + else: + s.append ('{}switch (buffer->cur ({}).codepoint)\n'.format(indent, index or '')) + s.append ('{}{{\n'.format (indent)) + cases = collections.defaultdict (set) + for first, rest in sorted (self._c.items ()): + cases[rest.__str__ (index + 1, depth + 2)].add (first) + for body, labels in sorted (list(cases.items ()), key=lambda b_ls: sorted (b_ls[1])[0]): + for i, cp in enumerate (sorted (labels)): + if i % 4 == 0: + s.append (self._indent (depth + 1)) + else: + s.append (' ') + s.append ('case 0x{:04X}u:{}'.format (cp, '\n' if i % 4 == 3 else '')) + if len (labels) % 4 != 0: + s.append ('\n') + s.append (body) + s.append ('{}break;\n'.format (self._indent (depth + 2))) + s.append ('{}}}\n'.format (indent)) + return ''.join (s) + +constraints = {} +with open (sys.argv[1], encoding='utf-8') as f: + constraints_header = [] + while True: + line = f.readline ().strip () + if line == '#': + break + constraints_header.append(line) + for line in f: + j = line.find ('#') + if j >= 0: + line = line[:j] + constraint = [int (cp, 16) for cp in line.split (';')[0].split ()] + if not constraint: continue + assert 2 <= len (constraint), 'Prohibited sequence is too short: {}'.format (constraint) + script = scripts[constraint[0]] + if script in constraints: + constraints[script].add (constraint) + else: + constraints[script] = ConstraintSet (constraint) + assert constraints, 'No constraints found' + +print ('/* == Start of generated functions == */') +print ('/*') +print (' * The following functions are generated by running:') +print (' *') +print((' * %s ms-use/IndicShapingInvalidCluster.txt Scripts.txt' % sys.argv[0])) +print (' *') +print (' * on files with these headers:') +print (' *') +for line in constraints_header: + print((' * %s' % line.strip ())) +print (' *') +for line in scripts_header: + print((' * %s' % line.strip ())) +print (' */') + +print () +print ('#include "hb.hh"') +print () +print ('#ifndef HB_NO_OT_SHAPE') +print () +print ('#include "hb-ot-shaper-vowel-constraints.hh"') +print () +print ('static void') +print ('_output_dotted_circle (hb_buffer_t *buffer)') +print ('{') +print (' (void) buffer->output_glyph (0x25CCu);') +print (' _hb_glyph_info_reset_continuation (&buffer->prev());') +print ('}') +print () +print ('static void') +print ('_output_with_dotted_circle (hb_buffer_t *buffer)') +print ('{') +print (' _output_dotted_circle (buffer);') +print (' (void) buffer->next_glyph ();') +print ('}') +print () + +print ('void') +print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,') +print ('\t\t\t\t hb_buffer_t *buffer,') +print ('\t\t\t\t hb_font_t *font HB_UNUSED)') +print ('{') +print ('#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS') +print (' return;') +print ('#endif') +print (' if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)') +print (' return;') +print () +print (' /* UGLY UGLY UGLY business of adding dotted-circle in the middle of') +print (' * vowel-sequences that look like another vowel. Data for each script') +print (' * collected from the USE script development spec.') +print (' *') +print (' * https://github.com/harfbuzz/harfbuzz/issues/1019') +print (' */') +print (' buffer->clear_output ();') +print (' unsigned int count = buffer->len;') +print (' switch ((unsigned) buffer->props.script)') +print (' {') + +for script, constraints in sorted (list(constraints.items ()), key=lambda s_c: script_order[s_c[0]]): + print((' case HB_SCRIPT_{}:'.format (script.upper ()))) + print (' for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)') + print (' {') + print ('\tbool matched = false;') + write (str (constraints)) + print ('\t(void) buffer->next_glyph ();') + print ('\tif (matched) _output_with_dotted_circle (buffer);') + print (' }') + print (' break;') + print () + +print (' default:') +print (' break;') +print (' }') +print (' buffer->sync ();') +print ('}') + +print () +print () +print ('#endif') +print ('/* == End of generated functions == */') diff --git a/gfx/harfbuzz/src/sample.py b/gfx/harfbuzz/src/sample.py index 654c8e8d5c..eef72de5d1 100755 --- a/gfx/harfbuzz/src/sample.py +++ b/gfx/harfbuzz/src/sample.py @@ -1,65 +1,66 @@ -#!/usr/bin/env python3 - -import sys -import array -import gi -gi.require_version('HarfBuzz', '0.0') -from gi.repository import HarfBuzz as hb -from gi.repository import GLib - -fontdata = open (sys.argv[1], 'rb').read () -text = sys.argv[2] -# Need to create GLib.Bytes explicitly until this bug is fixed: -# https://bugzilla.gnome.org/show_bug.cgi?id=729541 -blob = hb.glib_blob_create (GLib.Bytes.new (fontdata)) -face = hb.face_create (blob, 0) -del blob -font = hb.font_create (face) -upem = hb.face_get_upem (face) -del face -hb.font_set_scale (font, upem, upem) -#hb.ft_font_set_funcs (font) -hb.ot_font_set_funcs (font) - -buf = hb.buffer_create () -class Debugger (object): - def message (self, buf, font, msg, data, _x_what_is_this): - print (msg) - return True -debugger = Debugger () -hb.buffer_set_message_func (buf, debugger.message, 1, 0) - -## -## Add text to buffer -## -# -# See https://github.com/harfbuzz/harfbuzz/pull/271 -# -# If you do not care about cluster values reflecting Python -# string indices, then this is quickest way to add text to -# buffer: -# hb.buffer_add_utf8 (buf, text.encode('utf-8'), 0, -1) -# Otherwise, then following handles both narrow and wide -# Python builds (the first item in the array is BOM, so we skip it): -if sys.maxunicode == 0x10FFFF: - hb.buffer_add_utf32 (buf, array.array ('I', text.encode ('utf-32'))[1:], 0, -1) -else: - hb.buffer_add_utf16 (buf, array.array ('H', text.encode ('utf-16'))[1:], 0, -1) - - -hb.buffer_guess_segment_properties (buf) - -hb.shape (font, buf, []) -del font - -infos = hb.buffer_get_glyph_infos (buf) -positions = hb.buffer_get_glyph_positions (buf) - -for info, pos in zip (infos, positions): - gid = info.codepoint - cluster = info.cluster - x_advance = pos.x_advance - x_offset = pos.x_offset - y_offset = pos.y_offset - - print ("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset)) +#!/usr/bin/env python3 + +from __future__ import print_function +import sys +import array +import gi +gi.require_version('HarfBuzz', '0.0') +from gi.repository import HarfBuzz as hb +from gi.repository import GLib + +fontdata = open (sys.argv[1], 'rb').read () +text = sys.argv[2] +# Need to create GLib.Bytes explicitly until this bug is fixed: +# https://bugzilla.gnome.org/show_bug.cgi?id=729541 +blob = hb.glib_blob_create (GLib.Bytes.new (fontdata)) +face = hb.face_create (blob, 0) +del blob +font = hb.font_create (face) +upem = hb.face_get_upem (face) +del face +hb.font_set_scale (font, upem, upem) +#hb.ft_font_set_funcs (font) +hb.ot_font_set_funcs (font) + +buf = hb.buffer_create () +class Debugger (object): + def message (self, buf, font, msg, data, _x_what_is_this): + print (msg) + return True +debugger = Debugger () +hb.buffer_set_message_func (buf, debugger.message, 1, 0) + +## +## Add text to buffer +## +# +# See https://github.com/harfbuzz/harfbuzz/pull/271 +# +# If you do not care about cluster values reflecting Python +# string indices, then this is quickest way to add text to +# buffer: +# hb.buffer_add_utf8 (buf, text.encode('utf-8'), 0, -1) +# Otherwise, then following handles both narrow and wide +# Python builds (the first item in the array is BOM, so we skip it): +if sys.maxunicode == 0x10FFFF: + hb.buffer_add_utf32 (buf, array.array ('I', text.encode ('utf-32'))[1:], 0, -1) +else: + hb.buffer_add_utf16 (buf, array.array ('H', text.encode ('utf-16'))[1:], 0, -1) + + +hb.buffer_guess_segment_properties (buf) + +hb.shape (font, buf, []) +del font + +infos = hb.buffer_get_glyph_infos (buf) +positions = hb.buffer_get_glyph_positions (buf) + +for info, pos in zip (infos, positions): + gid = info.codepoint + cluster = info.cluster + x_advance = pos.x_advance + x_offset = pos.x_offset + y_offset = pos.y_offset + + print(("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset))) diff --git a/gfx/skia/generate_mozbuild.py b/gfx/skia/generate_mozbuild.py index 33594bd32c..ed770d733d 100755 --- a/gfx/skia/generate_mozbuild.py +++ b/gfx/skia/generate_mozbuild.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from __future__ import print_function import os import locale @@ -166,7 +167,7 @@ def generate_platform_sources(): for plat in platforms: if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=%s -D host_os=linux gyp/skia_lib.gyp" % plat) != 0: - print 'Failed to generate sources for ' + plat + print('Failed to generate sources for ' + plat) continue @@ -174,7 +175,7 @@ def generate_platform_sources(): sources[plat] = set(v.replace('../', 'skia/') for v in json.load(f)); f.close() - return dict(sources.items() + generate_opt_sources().items()) + return dict(list(sources.items()) + list(generate_opt_sources().items())) def generate_separated_sources(platform_sources): @@ -308,11 +309,11 @@ def generate_separated_sources(platform_sources): separated[key].add(value) if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=linux -D host_os=linux -R pdf gyp/pdf.gyp") != 0: - print 'Failed to generate sources for Skia PDF' + print('Failed to generate sources for Skia PDF') else: f = open('skia/sources.json'); separated['pdf'].add('skia/src/core/SkMD5.cpp'); - separated['pdf'].update(filter(lambda x: 'pdf' in x, set(v.replace('../', 'skia/') for v in json.load(f)))); + separated['pdf'].update([x for x in set(v.replace('../', 'skia/') for v in json.load(f)) if 'pdf' in x]); f.close() return separated @@ -479,7 +480,7 @@ def write_mozbuild(sources): f.close() - print 'Wrote ' + filename + print('Wrote ' + filename) def main(): platform_sources = generate_platform_sources() diff --git a/gfx/thebes/genTables.py b/gfx/thebes/genTables.py index 0e902c52aa..28374bd200 100644 --- a/gfx/thebes/genTables.py +++ b/gfx/thebes/genTables.py @@ -8,10 +8,10 @@ def table_generator(f): def generate(output): output.write("const uint8_t gfxUtils::sPremultiplyTable[256*256] = {\n"); - output.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n") + output.write(table_generator(lambda i: int((i // 256 * (i % 256) + 254) / 255)) + "\n") output.write("};\n"); output.write("const uint8_t gfxUtils::sUnpremultiplyTable[256*256] = {\n"); - output.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256) if (i / 256) > 0 else 255) % 256) + "\n") + output.write(table_generator(lambda i: int((i % 256) * 255 / (i // 256 if i // 256 > 0 else 255) % 256)) + "\n") output.write("};\n"); if __name__ == '__main__': diff --git a/intl/icu/source/python/icutools/databuilder/utils.py b/intl/icu/source/python/icutools/databuilder/utils.py index 3d53d18fae..5bd16393d0 100644 --- a/intl/icu/source/python/icutools/databuilder/utils.py +++ b/intl/icu/source/python/icutools/databuilder/utils.py @@ -77,12 +77,12 @@ def repeated_execution_request_looper(request): # dictionary of lists to list of dictionaries: ld = [ dict(zip(request.repeat_with, t)) - for t in zip(*request.repeat_with.values()) + for t in zip(*list(request.repeat_with.values())) ] if not ld: # No special options given in repeat_with ld = [{} for _ in range(len(request.input_files))] - return zip(ld, request.specific_dep_files, request.input_files, request.output_files) + return list(zip(ld, request.specific_dep_files, request.input_files, request.output_files)) def format_single_request_command(request, cmd_template, common_vars): diff --git a/intl/locale/props2arrays.py b/intl/locale/props2arrays.py index 510e0d51a0..3b3e564362 100644 --- a/intl/locale/props2arrays.py +++ b/intl/locale/props2arrays.py @@ -15,7 +15,7 @@ def main(header, propFile): if len(parts) == 2 and len(parts[0]) > 0: mappings[parts[0].strip()] = parts[1].strip() - keys = mappings.keys() + keys = list(mappings.keys()) keys.sort() header.write("// This is a generated file. Please do not edit.\n") diff --git a/intl/uconv/tools/gen-big5-data.py b/intl/uconv/tools/gen-big5-data.py index 1d0f59bb43..4bce14a368 100644 --- a/intl/uconv/tools/gen-big5-data.py +++ b/intl/uconv/tools/gen-big5-data.py @@ -91,7 +91,7 @@ static const char16_t kBig5LowBitsTable[] = { ''') for (low, high) in ranges: - for i in xrange(low, high): + for i in range(low, high): classFile.write(' 0x%04X,\n' % (index[i] & 0xFFFF)) classFile.write('''}; @@ -104,15 +104,15 @@ static const uint32_t kBig5AstralnessTable[] = { bits = [] for (low, high) in astralRanges: - for i in xrange(low, high): + for i in range(low, high): bits.append(1 if index[i] > 0xFFFF else 0) # pad length to multiple of 32 -for i in xrange(32 - (len(bits) % 32)): +for i in range(32 - (len(bits) % 32)): bits.append(0) i = 0 while i < len(bits): accu = 0 - for j in xrange(32): + for j in range(32): accu |= bits[i + j] << j classFile.write(' 0x%08X,\n' % accu) i += 32 @@ -190,7 +190,7 @@ preferLast = [ for codePoint in preferLast: # Python lists don't have .rindex() :-( - for i in xrange(len(index) - 1, -1, -1): + for i in range(len(index) - 1, -1, -1): candidate = index[i] if candidate == codePoint: classFile.write(''' case 0x%04X: diff --git a/ipc/chromium/src/third_party/libevent/event_rpcgen.py b/ipc/chromium/src/third_party/libevent/event_rpcgen.py index dead34c21c..06ef1d8f3f 100755 --- a/ipc/chromium/src/third_party/libevent/event_rpcgen.py +++ b/ipc/chromium/src/third_party/libevent/event_rpcgen.py @@ -14,6 +14,7 @@ # progress outputs that space stderr at the moment) # 3) emit other languages +from __future__ import print_function import sys import re @@ -33,7 +34,7 @@ headerdirect = [] cppdirect = [] def TranslateList(mylist, mydict): - return map(lambda x: x % mydict, mylist) + return [x % mydict for x in mylist] # Exception class for parse errors class RpcGenError(Exception): @@ -48,17 +49,17 @@ class Struct: self._name = name self._entries = [] self._tags = {} - print >>sys.stderr, ' Created struct: %s' % name + print(' Created struct: %s' % name, file=sys.stderr) def AddEntry(self, entry): - if self._tags.has_key(entry.Tag()): + if entry.Tag() in self._tags: raise RpcGenError( 'Entry "%s" duplicates tag number %d from "%s" ' 'around line %d' % (entry.Name(), entry.Tag(), self._tags[entry.Tag()], line_count)) self._entries.append(entry) self._tags[entry.Tag()] = entry.Name() - print >>sys.stderr, ' Added entry: %s' % entry.Name() + print(' Added entry: %s' % entry.Name(), file=sys.stderr) def Name(self): return self._name @@ -72,7 +73,7 @@ class Struct: def PrintIndented(self, file, ident, code): """Takes an array, add indentation to each entry and prints it.""" for entry in code: - print >>file, '%s%s' % (ident, entry) + print('%s%s' % (ident, entry), file=file) class StructCCode(Struct): """ Knows how to generate C code for a struct """ @@ -82,20 +83,20 @@ class StructCCode(Struct): def PrintTags(self, file): """Prints the tag definitions for a structure.""" - print >>file, '/* Tag definition for %s */' % self._name - print >>file, 'enum %s_ {' % self._name.lower() + print('/* Tag definition for %s */' % self._name, file=file) + print('enum %s_ {' % self._name.lower(), file=file) for entry in self._entries: - print >>file, ' %s=%d,' % (self.EntryTagName(entry), - entry.Tag()) - print >>file, ' %s_MAX_TAGS' % (self._name.upper()) - print >>file, '};\n' + print(' %s=%d,' % (self.EntryTagName(entry), + entry.Tag()), file=file) + print(' %s_MAX_TAGS' % (self._name.upper()), file=file) + print('};\n', file=file) def PrintForwardDeclaration(self, file): - print >>file, 'struct %s;' % self._name + print('struct %s;' % self._name, file=file) def PrintDeclaration(self, file): - print >>file, '/* Structure declaration for %s */' % self._name - print >>file, 'struct %s_access_ {' % self._name + print('/* Structure declaration for %s */' % self._name, file=file) + print('struct %s_access_ {' % self._name, file=file) for entry in self._entries: dcl = entry.AssignDeclaration('(*%s_assign)' % entry.Name()) dcl.extend( @@ -104,20 +105,19 @@ class StructCCode(Struct): dcl.extend( entry.AddDeclaration('(*%s_add)' % entry.Name())) self.PrintIndented(file, ' ', dcl) - print >>file, '};\n' + print('};\n', file=file) - print >>file, 'struct %s {' % self._name - print >>file, ' struct %s_access_ *base;\n' % self._name + print('struct %s {' % self._name, file=file) + print(' struct %s_access_ *base;\n' % self._name, file=file) for entry in self._entries: dcl = entry.Declaration() self.PrintIndented(file, ' ', dcl) - print >>file, '' + print('', file=file) for entry in self._entries: - print >>file, ' ev_uint8_t %s_set;' % entry.Name() - print >>file, '};\n' + print(' ev_uint8_t %s_set;' % entry.Name(), file=file) + print('};\n', file=file) - print >>file, \ -"""struct %(name)s *%(name)s_new(void); + print("""struct %(name)s *%(name)s_new(void); struct %(name)s *%(name)s_new_with_arg(void *); void %(name)s_free(struct %(name)s *); void %(name)s_clear(struct %(name)s *); @@ -127,7 +127,7 @@ int %(name)s_complete(struct %(name)s *); void evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t, const struct %(name)s *); int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, - struct %(name)s *);""" % { 'name' : self._name } + struct %(name)s *);""" % { 'name' : self._name }, file=file) # Write a setting function of every variable @@ -140,22 +140,21 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, self.PrintIndented(file, '', entry.AddDeclaration( entry.AddFuncName())) - print >>file, '/* --- %s done --- */\n' % self._name + print('/* --- %s done --- */\n' % self._name, file=file) def PrintCode(self, file): - print >>file, ('/*\n' + print(('/*\n' ' * Implementation of %s\n' - ' */\n') % self._name + ' */\n') % self._name, file=file) - print >>file, \ - 'static struct %(name)s_access_ __%(name)s_base = {' % \ - { 'name' : self._name } + print('static struct %(name)s_access_ __%(name)s_base = {' % \ + { 'name' : self._name }, file=file) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeBase()) - print >>file, '};\n' + print('};\n', file=file) # Creation - print >>file, ( + print(( 'struct %(name)s *\n' '%(name)s_new(void)\n' '{\n' @@ -170,77 +169,77 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' event_warn("%%s: malloc", __func__);\n' ' return (NULL);\n' ' }\n' - ' tmp->base = &__%(name)s_base;\n') % { 'name' : self._name } + ' tmp->base = &__%(name)s_base;\n') % { 'name' : self._name }, file=file) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeInitialize('tmp')) - print >>file, ' tmp->%s_set = 0;\n' % entry.Name() + print(' tmp->%s_set = 0;\n' % entry.Name(), file=file) - print >>file, ( + print(( ' return (tmp);\n' - '}\n') + '}\n'), file=file) # Adding for entry in self._entries: if entry.Array(): self.PrintIndented(file, '', entry.CodeAdd()) - print >>file, '' + print('', file=file) # Assigning for entry in self._entries: self.PrintIndented(file, '', entry.CodeAssign()) - print >>file, '' + print('', file=file) # Getting for entry in self._entries: self.PrintIndented(file, '', entry.CodeGet()) - print >>file, '' + print('', file=file) # Clearing - print >>file, ( 'void\n' + print(( 'void\n' '%(name)s_clear(struct %(name)s *tmp)\n' '{' - ) % { 'name' : self._name } + ) % { 'name' : self._name }, file=file) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeClear('tmp')) - print >>file, '}\n' + print('}\n', file=file) # Freeing - print >>file, ( 'void\n' + print(( 'void\n' '%(name)s_free(struct %(name)s *tmp)\n' '{' - ) % { 'name' : self._name } + ) % { 'name' : self._name }, file=file) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeFree('tmp')) - print >>file, (' free(tmp);\n' - '}\n') + print((' free(tmp);\n' + '}\n'), file=file) # Marshaling - print >>file, ('void\n' + print(('void\n' '%(name)s_marshal(struct evbuffer *evbuf, ' 'const struct %(name)s *tmp)' - '{') % { 'name' : self._name } + '{') % { 'name' : self._name }, file=file) for entry in self._entries: indent = ' ' # Optional entries do not have to be set if entry.Optional(): indent += ' ' - print >>file, ' if (tmp->%s_set) {' % entry.Name() + print(' if (tmp->%s_set) {' % entry.Name(), file=file) self.PrintIndented( file, indent, entry.CodeMarshal('evbuf', self.EntryTagName(entry), entry.GetVarName('tmp'), entry.GetVarLen('tmp'))) if entry.Optional(): - print >>file, ' }' + print(' }', file=file) - print >>file, '}\n' + print('}\n', file=file) # Unmarshaling - print >>file, ('int\n' + print(('int\n' '%(name)s_unmarshal(struct %(name)s *tmp, ' ' struct evbuffer *evbuf)\n' '{\n' @@ -249,14 +248,14 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' if (evtag_peek(evbuf, &tag) == -1)\n' ' return (-1);\n' ' switch (tag) {\n' - ) % { 'name' : self._name } + ) % { 'name' : self._name }, file=file) for entry in self._entries: - print >>file, ' case %s:\n' % self.EntryTagName(entry) + print(' case %s:\n' % self.EntryTagName(entry), file=file) if not entry.Array(): - print >>file, ( + print(( ' if (tmp->%s_set)\n' ' return (-1);' - ) % (entry.Name()) + ) % (entry.Name()), file=file) self.PrintIndented( file, ' ', @@ -265,26 +264,26 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, entry.GetVarName('tmp'), entry.GetVarLen('tmp'))) - print >>file, ( ' tmp->%s_set = 1;\n' % entry.Name() + - ' break;\n' ) - print >>file, ( ' default:\n' + print(( ' tmp->%s_set = 1;\n' % entry.Name() + + ' break;\n' ), file=file) + print(( ' default:\n' ' return -1;\n' ' }\n' - ' }\n' ) + ' }\n' ), file=file) # Check if it was decoded completely - print >>file, ( ' if (%(name)s_complete(tmp) == -1)\n' + print(( ' if (%(name)s_complete(tmp) == -1)\n' ' return (-1);' - ) % { 'name' : self._name } + ) % { 'name' : self._name }, file=file) # Successfully decoded - print >>file, ( ' return (0);\n' - '}\n') + print(( ' return (0);\n' + '}\n'), file=file) # Checking if a structure has all the required data - print >>file, ( + print(( 'int\n' '%(name)s_complete(struct %(name)s *msg)\n' - '{' ) % { 'name' : self._name } + '{' ) % { 'name' : self._name }, file=file) for entry in self._entries: if not entry.Optional(): code = [ @@ -297,12 +296,12 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, self.PrintIndented( file, ' ', entry.CodeComplete('msg', entry.GetVarName('msg'))) - print >>file, ( + print(( ' return (0);\n' - '}\n' ) + '}\n' ), file=file) # Complete message unmarshaling - print >>file, ( + print(( 'int\n' 'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, ' 'ev_uint32_t need_tag, struct %(name)s *msg)\n' @@ -324,10 +323,10 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' error:\n' ' evbuffer_free(tmp);\n' ' return (res);\n' - '}\n' ) % { 'name' : self._name } + '}\n' ) % { 'name' : self._name }, file=file) # Complete message marshaling - print >>file, ( + print(( 'void\n' 'evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, ' 'const struct %(name)s *msg)\n' @@ -337,7 +336,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' %(name)s_marshal(_buf, msg);\n' ' evtag_marshal_buffer(evbuf, tag, _buf);\n ' ' evbuffer_free(_buf);\n' - '}\n' ) % { 'name' : self._name } + '}\n' ) % { 'name' : self._name }, file=file) class Entry: def __init__(self, type, name, tag): @@ -1121,7 +1120,7 @@ class EntryArray(Entry): codearrayassign = self._entry.CodeArrayAssign( 'msg->%(name)s_data[off]' % self.GetTranslation(), 'value') - code += map(lambda x: ' ' + x, codearrayassign) + code += [' ' + x for x in codearrayassign] code += TranslateList([ ' }', @@ -1162,7 +1161,7 @@ class EntryArray(Entry): code = TranslateList(code, self.GetTranslation()) - code += map(lambda x: ' ' + x, codearrayadd) + code += [' ' + x for x in codearrayadd] code += TranslateList([ ' msg->%(name)s_set = 1;', @@ -1190,7 +1189,7 @@ class EntryArray(Entry): code = TranslateList(code, translate) - code += map(lambda x: ' ' + x, tmp) + code += [' ' + x for x in tmp] code += [ ' }', @@ -1255,7 +1254,7 @@ class EntryArray(Entry): code = TranslateList(code, translate) if codearrayfree: - code += map(lambda x: ' ' + x, codearrayfree) + code += [' ' + x for x in codearrayfree] code += [ ' }' ] @@ -1668,31 +1667,31 @@ class CommandLine: impl_file = self.impl_file factory = self.factory - print >>sys.stderr, 'Reading \"%s\"' % filename + print('Reading \"%s\"' % filename, file=sys.stderr) fp = open(filename, 'r') entities = Parse(factory, fp) fp.close() - print >>sys.stderr, '... creating "%s"' % header_file + print('... creating "%s"' % header_file, file=sys.stderr) header_fp = open(header_file, 'w') - print >>header_fp, factory.HeaderPreamble(filename) + print(factory.HeaderPreamble(filename), file=header_fp) # Create forward declarations: allows other structs to reference # each other for entry in entities: entry.PrintForwardDeclaration(header_fp) - print >>header_fp, '' + print('', file=header_fp) for entry in entities: entry.PrintTags(header_fp) entry.PrintDeclaration(header_fp) - print >>header_fp, factory.HeaderPostamble(filename) + print(factory.HeaderPostamble(filename), file=header_fp) header_fp.close() - print >>sys.stderr, '... creating "%s"' % impl_file + print('... creating "%s"' % impl_file, file=sys.stderr) impl_fp = open(impl_file, 'w') - print >>impl_fp, factory.BodyPreamble(filename, header_file) + print(factory.BodyPreamble(filename, header_file), file=impl_fp) for entry in entities: entry.PrintCode(impl_fp) impl_fp.close() @@ -1702,16 +1701,16 @@ if __name__ == '__main__': CommandLine(sys.argv).run() sys.exit(0) - except RpcGenError, e: - print >>sys.stderr, e + except RpcGenError as e: + print(e, file=sys.stderr) sys.exit(1) - except EnvironmentError, e: + except EnvironmentError as e: if e.filename and e.strerror: - print >>sys.stderr, "%s: %s" % (e.filename, e.strerror) + print("%s: %s" % (e.filename, e.strerror), file=sys.stderr) sys.exit(1) elif e.strerror: - print >> sys.stderr, e.strerror + print(e.strerror, file=sys.stderr) sys.exit(1) else: raise diff --git a/ipc/ipdl/ipdl.py b/ipc/ipdl/ipdl.py index 2220b4f837..01a39bb195 100755 --- a/ipc/ipdl/ipdl.py +++ b/ipc/ipdl/ipdl.py @@ -2,8 +2,9 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import optparse, os, re, sys -from cStringIO import StringIO +from io import StringIO from mozbuild.pythonutil import iter_modules_in_path import mozpack.path as mozpath import itertools @@ -12,7 +13,7 @@ import ipdl def log(minv, fmt, *args): if _verbosity >= minv: - print fmt % args + print(fmt % args) # process command line @@ -69,7 +70,7 @@ for (path, dirs, headers) in os.walk(headersdir): base = os.path.basename(h) if base in headersmap: root, ext = os.path.splitext(base) - print >>sys.stderr, 'A protocol named', root, 'exists in multiple namespaces' + print('A protocol named', root, 'exists in multiple namespaces', file=sys.stderr) sys.exit(1) headersmap[base] = os.path.join(path, h) @@ -127,12 +128,12 @@ for f in files: ast = ipdl.parse(specstring, filename, includedirs=includedirs) if ast is None: - print >>sys.stderr, 'Specification could not be parsed.' + print('Specification could not be parsed.', file=sys.stderr) sys.exit(1) log(2, 'checking types') if not ipdl.typecheck(ast): - print >>sys.stderr, 'Specification is not well typed.' + print('Specification is not well typed.', file=sys.stderr) sys.exit(1) if _verbosity > 2: @@ -154,30 +155,30 @@ allprotocols.sort() ipcmsgstart = StringIO() -print >>ipcmsgstart, """ +print(""" // CODE GENERATED by ipdl.py. Do not edit. #ifndef IPCMessageStart_h #define IPCMessageStart_h enum IPCMessageStart { -""" +""", file=ipcmsgstart) for name in allprotocols: - print >>ipcmsgstart, " %s," % name - print >>ipcmsgstart, " %sChild," % name + print(" %s," % name, file=ipcmsgstart) + print(" %sChild," % name, file=ipcmsgstart) -print >>ipcmsgstart, """ +print(""" LastMsgIndex }; static_assert(LastMsgIndex <= 65536, "need to update IPC_MESSAGE_MACRO"); #endif // ifndef IPCMessageStart_h -""" +""", file=ipcmsgstart) ipc_msgtype_name = StringIO() -print >>ipc_msgtype_name, """ +print(""" // CODE GENERATED by ipdl.py. Do not edit. #include @@ -188,16 +189,16 @@ using std::uint32_t; namespace { enum IPCMessages { -""" +""", file=ipc_msgtype_name) for protocol in sorted(allmessages.keys()): for (msg, num) in allmessages[protocol].idnums: if num: - print >>ipc_msgtype_name, " %s = %s," % (msg, num) + print(" %s = %s," % (msg, num), file=ipc_msgtype_name) elif not msg.endswith('End'): - print >>ipc_msgtype_name, " %s__%s," % (protocol, msg) + print(" %s__%s," % (protocol, msg), file=ipc_msgtype_name) -print >>ipc_msgtype_name, """ +print(""" }; } // anonymous namespace @@ -208,17 +209,17 @@ namespace ipc { const char* StringFromIPCMessageType(uint32_t aMessageType) { switch (aMessageType) { -""" +""", file=ipc_msgtype_name) for protocol in sorted(allmessages.keys()): for (msg, num) in allmessages[protocol].idnums: if num or msg.endswith('End'): continue - print >>ipc_msgtype_name, """ + print(""" case %s__%s: - return "%s::%s";""" % (protocol, msg, protocol, msg) + return "%s::%s";""" % (protocol, msg, protocol, msg), file=ipc_msgtype_name) -print >>ipc_msgtype_name, """ +print(""" default: return "???"; } @@ -226,7 +227,7 @@ print >>ipc_msgtype_name, """ } // namespace ipc } // namespace mozilla -""" +""", file=ipc_msgtype_name) ipdl.writeifmodified(ipcmsgstart.getvalue(), ipcmessagestartpath) ipdl.writeifmodified(ipc_msgtype_name.getvalue(), ipc_msgtype_name_path) diff --git a/ipc/ipdl/ipdl/__init__.py b/ipc/ipdl/ipdl/__init__.py index d2d883f861..5d169d422a 100644 --- a/ipc/ipdl/ipdl/__init__.py +++ b/ipc/ipdl/ipdl/__init__.py @@ -5,7 +5,7 @@ __all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified' ] import os, sys -from cStringIO import StringIO +from io import StringIO from ipdl.cgen import IPDLCodeGen from ipdl.lower import LowerToCxx, msgenums @@ -68,10 +68,10 @@ def writeifmodified(contents, file): oldcontents = None if os.path.exists(file): - fd = open(file, 'rb') + fd = open(file, 'r') oldcontents = fd.read() fd.close() if oldcontents != contents: - fd = open(file, 'wb') + fd = open(file, 'w') fd.write(contents) fd.close() diff --git a/ipc/ipdl/ipdl/ast.py b/ipc/ipdl/ipdl/ast.py index a8bd1e41f7..66cbb130e3 100644 --- a/ipc/ipdl/ipdl/ast.py +++ b/ipc/ipdl/ipdl/ast.py @@ -13,8 +13,8 @@ HIGH_PRIORITY = 2 class Visitor: def defaultVisit(self, node): - raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% ( - node.__class__.__name__) + raise Exception("INTERNAL ERROR: no visitor for node type `%s'"% ( + node.__class__.__name__)) def visitTranslationUnit(self, tu): for cxxInc in tu.cxxIncludes: @@ -320,7 +320,7 @@ class MessageDecl(Node): elif modifier == 'verify': self.verify = modifier elif modifier != '': - raise Exception, "Unexpected message modifier `%s'"% modifier + raise Exception("Unexpected message modifier `%s'"% modifier) class Transition(Node): def __init__(self, loc, trigger, msg, toStates): diff --git a/ipc/ipdl/ipdl/cxx/ast.py b/ipc/ipdl/ipdl/cxx/ast.py index 18c2b3f1db..125942f47e 100644 --- a/ipc/ipdl/ipdl/cxx/ast.py +++ b/ipc/ipdl/ipdl/cxx/ast.py @@ -3,11 +3,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import copy, sys +from functools import reduce class Visitor: def defaultVisit(self, node): - raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% ( - node.__class__.__name__) + raise Exception("INTERNAL ERROR: no visitor for node type `%s'"% ( + node.__class__.__name__)) def visitWhitespace(self, ws): pass @@ -375,11 +376,11 @@ class Typedef(Node): self.totypename = totypename self.templateargs = templateargs - def __cmp__(self, o): - return cmp(self.totypename, o.totypename) + def __lt__(self, o): + return self.totypename < o.totypename def __eq__(self, o): return (self.__class__ == o.__class__ - and 0 == cmp(self, o)) + and self.totypename == o.totypename) def __hash__(self): return hash(self.totypename) diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 61855a7a9e..4b373fda7d 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -1730,7 +1730,7 @@ class _GenerateProtocolCode(ipdl.ast.Visitor): transitions.append(ifsametrigger) msgToTransitions[msgid] = transitions - for msgid, transitions in msgToTransitions.iteritems(): + for msgid, transitions in msgToTransitions.items(): block = Block() block.addstmts(transitions +[ StmtBreak() ]) msgswitch.addcase(CaseLabel(msgid), block) diff --git a/ipc/ipdl/ipdl/parser.py b/ipc/ipdl/ipdl/parser.py index 38c46dc73a..6cb99163a5 100644 --- a/ipc/ipdl/ipdl/parser.py +++ b/ipc/ipdl/ipdl/parser.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import os, sys from ply import lex, yacc @@ -78,8 +79,8 @@ class Parser: try: ast = self.parser.parse(input=input, lexer=self.lexer, debug=self.debug) - except ParseError, p: - print >>errout, p + except ParseError as p: + print(p, file=errout) return None Parser.current = Parser.parseStack.pop() @@ -648,7 +649,7 @@ def p_Nested(p): if p[1] not in kinds: _error(locFromTok(p, 1), "Expected not, inside_sync, or inside_cpow for nested()") - p[0] = { 'nested': kinds[p[1]] } + p[0] = kinds[p[1]] def p_Priority(p): """Priority : ID""" @@ -662,7 +663,10 @@ def p_Priority(p): def p_SendQualifier(p): """SendQualifier : NESTED '(' Nested ')' | PRIO '(' Priority ')'""" - p[0] = p[3] + if p[1] == 'nested': + p[0] = {'nested': p[3]} + else: + p[0] = p[3] def p_SendQualifierList(p): """SendQualifierList : SendQualifier SendQualifierList diff --git a/ipc/ipdl/ipdl/type.py b/ipc/ipdl/ipdl/type.py index 66a9fbd3ff..a6e8dbd845 100644 --- a/ipc/ipdl/ipdl/type.py +++ b/ipc/ipdl/ipdl/type.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import os, sys from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, State, StructDecl, TransitionStmt @@ -10,6 +11,7 @@ from ipdl.ast import ASYNC, SYNC, INTR from ipdl.ast import IN, OUT, INOUT, ANSWER, CALL, RECV, SEND from ipdl.ast import NOT_NESTED, INSIDE_SYNC_NESTED, INSIDE_CPOW_NESTED import ipdl.builtin as builtin +from functools import reduce _DELETE_MSG = '__delete__' @@ -22,7 +24,7 @@ def _otherside(side): def unique_pairs(s): n = len(s) for i, e1 in enumerate(s): - for j in xrange(i+1, n): + for j in range(i+1, n): yield (e1, s[j]) def cartesian_product(s1, s2): @@ -36,8 +38,8 @@ class TypeVisitor: self.visited = set() def defaultVisit(self, node, *args): - raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% ( - node.__class__.__name__) + raise Exception("INTERNAL ERROR: no visitor for node type `%s'"% ( + node.__class__.__name__)) def visitVoidType(self, v, *args): pass @@ -125,8 +127,8 @@ class Type: def typename(self): return self.__class__.__name__ - def name(self): raise Exception, 'NYI' - def fullname(self): raise Exception, 'NYI' + def name(self): raise Exception('NYI') + def fullname(self): raise Exception('NYI') def accept(self, visitor, *args): visit = getattr(visitor, 'visit'+ self.__class__.__name__, None) @@ -506,7 +508,7 @@ def hasactor(type): def hasshmem(type): """Return true iff |type| is shmem or has it buried within.""" - class found: pass + class found(Exception): pass class findShmem(TypeVisitor): def visitShmemType(self, s): raise found() try: @@ -517,7 +519,7 @@ def hasshmem(type): def hasfd(type): """Return true iff |type| is fd or has it buried within.""" - class found: pass + class found(Exception): pass class findFD(TypeVisitor): def visitFDType(self, s): raise found() try: @@ -647,7 +649,7 @@ With this information, it finally type checks the AST.''' def reportErrors(self, errout): for error in self.errors: - print >>errout, error + print(error, file=errout) class TcheckVisitor(Visitor): @@ -1581,7 +1583,7 @@ class Process: self.spawn.add(spawn) def iteredges(self): - for edgelist in self.edges.itervalues(): + for edgelist in self.edges.values(): for edge in edgelist: yield edge @@ -1690,7 +1692,7 @@ class ProcessGraph: @classmethod def iterbridges(cls): - for edges in cls.bridges.itervalues(): + for edges in cls.bridges.values(): for bridge in edges: yield bridge @@ -1711,7 +1713,7 @@ class ProcessGraph: @classmethod def iteropens(cls): - for edges in cls.opens.itervalues(): + for edges in cls.opens.values(): for opens in edges: yield opens @@ -1879,19 +1881,19 @@ class CheckProcessGraph(TcheckVisitor): # is a dag def visitTranslationUnit(self, tu): if 0: - print 'Processes' + print('Processes') for process in ProcessGraph.processes: - print ' ', process + print(' ', process) for edge in process.iteredges(): - print ' ', edge - print 'Bridges' - for bridgeList in ProcessGraph.bridges.itervalues(): + print(' ', edge) + print('Bridges') + for bridgeList in ProcessGraph.bridges.values(): for bridge in bridgeList: - print ' ', bridge - print 'Opens' - for opensList in ProcessGraph.opens.itervalues(): + print(' ', bridge) + print('Opens') + for opensList in ProcessGraph.opens.values(): for opens in opensList: - print ' ', opens + print(' ', opens) ##----------------------------------------------------------------------------- @@ -2088,19 +2090,19 @@ direction as trigger |t|''' errT2 = None if 0 == len(U1) or 0 == len(U2): - print "******* case 1" + print("******* case 1") raceError = True elif 1 < len(U1) or 1 < len(U2): raceError = True # there are potentially many unpaired states; just # pick two - print "******* case 2" + print("******* case 2") for u1, u2 in cartesian_product(U1, U2): if u1 != u2: errT1, errT2 = u1, u2 break elif U1 != U2: - print "******* case 3" + print("******* case 3") raceError = True for errT1 in U1: pass for errT2 in U2: pass @@ -2140,7 +2142,7 @@ direction as trigger |t|''' root.loc, "when starting from state `%s', actors of protocol `%s' cannot be deleted", root.state.name, p.name) - for ts in p.states.itervalues(): + for ts in p.states.values(): if ts.state is not State.DEAD and ts.state not in allvisited: self.error(ts.loc, "unreachable state `%s' in protocol `%s'", diff --git a/ipc/ipdl/test/cxx/genIPDLUnitTests.py b/ipc/ipdl/test/cxx/genIPDLUnitTests.py index 24026451bc..e1c29798b2 100644 --- a/ipc/ipdl/test/cxx/genIPDLUnitTests.py +++ b/ipc/ipdl/test/cxx/genIPDLUnitTests.py @@ -2,10 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import string, sys def usage(): - print >>sys.stderr, """ + print(""" %s template_file -t unit_tests... -e extra_protocols... TEMPLATE_FILE is used to generate to generate the unit-tester .cpp @@ -13,7 +14,7 @@ def usage(): EXTRA_PROTOCOLS are top-level protocols for subprocesses that can be spawned in tests but are not unit tests in and of themselves -"""% (sys.argv[0]) +"""% (sys.argv[0]), file=sys.stderr) sys.exit(1) def main(argv): diff --git a/ipc/pull-chromium.py b/ipc/pull-chromium.py index c4a476e425..114360ca31 100644 --- a/ipc/pull-chromium.py +++ b/ipc/pull-chromium.py @@ -12,6 +12,7 @@ http://dev.chromium.org/developers/how-tos/get-the-code for details about doing this efficiently. """ +from __future__ import print_function import sys, os from subprocess import check_call from shutil import rmtree @@ -19,11 +20,11 @@ from shutil import rmtree topsrcdir, chromiumtree, rev = sys.argv[1:] if not os.path.exists(os.path.join(topsrcdir, 'client.py')): - print >>sys.stderr, "Incorrect topsrcdir" + print("Incorrect topsrcdir", file=sys.stderr) sys.exit(1) if not os.path.exists(os.path.join(chromiumtree, 'src/DEPS')): - print >>sys.stderr, "Incorrect chromium directory, missing DEPS" + print("Incorrect chromium directory, missing DEPS", file=sys.stderr) sys.exit(1) check_call(['gclient', 'sync', '--force', '--revision=src@%s' % rev], cwd=chromiumtree) diff --git a/js/src/builtin/embedjs.py b/js/src/builtin/embedjs.py index c642aebd51..87a269259e 100644 --- a/js/src/builtin/embedjs.py +++ b/js/src/builtin/embedjs.py @@ -37,6 +37,7 @@ # It uses the C preprocessor to process its inputs. from __future__ import with_statement +from __future__ import print_function import re, sys, os, subprocess import shlex import which @@ -53,7 +54,7 @@ def ToCAsciiArray(lines): def ToCArray(lines): result = [] for chr in lines: - result.append(str(ord(chr))) + result.append(str(chr if isinstance(chr, int) else ord(chr))) return ", ".join(result) HEADER_TEMPLATE = """\ @@ -87,7 +88,7 @@ def embed(cxx, preprocessorOption, msgs, sources, c_out, js_out, namespace, env) js_out.write(processed) import zlib - compressed = zlib.compress(processed) + compressed = zlib.compress(processed.encode('utf-8')) data = ToCArray(compressed) c_out.write(HEADER_TEMPLATE % { 'sources_type': 'unsigned char', @@ -107,9 +108,9 @@ def preprocess(cxx, preprocessorOption, source, args = []): tmpOut = 'self-hosting-preprocessed.pp'; outputArg = shlex.split(preprocessorOption + tmpOut) - with open(tmpIn, 'wb') as input: + with open(tmpIn, 'w') as input: input.write(source) - print(' '.join(cxx + outputArg + args + [tmpIn])) + print((' '.join(cxx + outputArg + args + [tmpIn]))) result = subprocess.Popen(cxx + outputArg + args + [tmpIn]).wait() if (result != 0): sys.exit(result); @@ -132,7 +133,7 @@ def messages(jsmsg): def get_config_defines(buildconfig): # Collect defines equivalent to ACDEFINES and add MOZ_DEBUG_DEFINES. - env = {key: value for key, value in buildconfig.defines.iteritems() + env = {key: value for key, value in buildconfig.defines.items() if key not in buildconfig.non_global_defines} for define in buildconfig.substs['MOZ_DEBUG_DEFINES']: env[define] = 1 diff --git a/js/src/builtin/intl/make_intl_data.py b/js/src/builtin/intl/make_intl_data.py index 7cd4b2c652..fb6db50b88 100644 --- a/js/src/builtin/intl/make_intl_data.py +++ b/js/src/builtin/intl/make_intl_data.py @@ -31,20 +31,23 @@ import codecs import sys import tarfile import tempfile -import urllib2 +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse from contextlib import closing from functools import partial -from itertools import chain, ifilter, ifilterfalse, imap, izip_longest, groupby, tee +from itertools import chain, groupby, tee from operator import attrgetter, itemgetter -from urlparse import urlsplit +from urllib.parse import urlsplit from zipfile import ZipFile +import six +from six.moves import filterfalse +from itertools import zip_longest # From https://docs.python.org/3/library/itertools.html def grouper(iterable, n, fillvalue=None): "Collect data into fixed-length chunks or blocks" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n - return izip_longest(*args, fillvalue=fillvalue) + return zip_longest(*args, fillvalue=fillvalue) def writeMappingHeader(println, description, source, url): if type(description) is not list: @@ -64,7 +67,7 @@ def writeMappingsVar(println, mapping, name, description, source, url): println(u"") writeMappingHeader(println, description, source, url) println(u"var {0} = {{".format(name)) - for (key, value) in sorted(mapping.items(), key=itemgetter(0)): + for (key, value) in sorted(list(mapping.items()), key=itemgetter(0)): println(u' "{0}": "{1}",'.format(key, value)) println(u"};") @@ -103,7 +106,7 @@ bool js::intl::LanguageTag::{0}({1} {2}) {{ # Sort the subtags by length. That enables using an optimized comparator # for the binary search, which only performs a single |memcmp| for multiple # of two subtag lengths. - mappings_keys = mappings.keys() if type(mappings) == dict else mappings + mappings_keys = list(mappings.keys()) if type(mappings) == dict else mappings for (length, subtags) in groupby(sorted(mappings_keys, key=len), len): # Omit the length check if the current length is the maximum length. if length != tag_maxlength: @@ -198,7 +201,7 @@ void js::intl::LanguageTag::performComplexLanguageMappings() { # Merge duplicate language entries. language_aliases = {} for (deprecated_language, (language, script, region)) in ( - sorted(complex_language_mappings.items(), key=itemgetter(0)) + sorted(list(complex_language_mappings.items()), key=itemgetter(0)) ): key = (language, script, region) if key not in language_aliases: @@ -208,7 +211,7 @@ void js::intl::LanguageTag::performComplexLanguageMappings() { first_language = True for (deprecated_language, (language, script, region)) in ( - sorted(complex_language_mappings.items(), key=itemgetter(0)) + sorted(list(complex_language_mappings.items()), key=itemgetter(0)) ): key = (language, script, region) if deprecated_language in language_aliases[key]: @@ -265,7 +268,7 @@ void js::intl::LanguageTag::performComplexRegionMappings() { # Merge duplicate region entries. region_aliases = {} for (deprecated_region, (default, non_default_replacements)) in ( - sorted(complex_region_mappings.items(), key=itemgetter(0)) + sorted(list(complex_region_mappings.items()), key=itemgetter(0)) ): key = hash_key(default, non_default_replacements) if key not in region_aliases: @@ -275,7 +278,7 @@ void js::intl::LanguageTag::performComplexRegionMappings() { first_region = True for (deprecated_region, (default, non_default_replacements)) in ( - sorted(complex_region_mappings.items(), key=itemgetter(0)) + sorted(list(complex_region_mappings.items()), key=itemgetter(0)) ): key = hash_key(default, non_default_replacements) if deprecated_region in region_aliases[key]: @@ -380,7 +383,7 @@ bool js::intl::LanguageTag::performVariantMappings(JSContext* cx) { first_variant = True for (deprecated_variant, (type, replacement)) in ( - sorted(variant_mappings.items(), key=itemgetter(0)) + sorted(list(variant_mappings.items()), key=itemgetter(0)) ): if_kind = u"if" if first_variant else u"else if" first_variant = False @@ -498,7 +501,7 @@ bool js::intl::LanguageTag::updateGrandfatheredMappings(JSContext* cx) { is_first = True - for (tag, modern) in sorted(grandfathered_mappings.items(), key=itemgetter(0)): + for (tag, modern) in sorted(list(grandfathered_mappings.items()), key=itemgetter(0)): tag_match = re_unicode_locale_id.match(tag) assert tag_match is not None @@ -1152,7 +1155,7 @@ static bool IsCanonicallyCasedTransformType(mozilla::Span type) { "const LanguageSubtag&", "language", "IsStructurallyValidLanguageTag", "IsCanonicallyCasedLanguageTag", - complex_language_mappings.keys(), language_maxlength, + list(complex_language_mappings.keys()), language_maxlength, "Language subtags with complex mappings.", source, url) writeMappingsBinarySearch(println, "regionMapping", "RegionSubtag&", "region", @@ -1164,7 +1167,7 @@ static bool IsCanonicallyCasedTransformType(mozilla::Span type) { "const RegionSubtag&", "region", "IsStructurallyValidRegionTag", "IsCanonicallyCasedRegionTag", - complex_region_mappings.keys(), region_maxlength, + list(complex_region_mappings.keys()), region_maxlength, "Region subtags with complex mappings.", source, url) writeComplexLanguageTagMappings(println, complex_language_mappings, @@ -1360,7 +1363,7 @@ def updateCLDRLangTags(args): readFiles(cldr_file) else: print("Downloading CLDR core.zip...") - with closing(urllib2.urlopen(url)) as cldr_file: + with closing(six.moves.urllib.request.urlopen(url)) as cldr_file: cldr_data = io.BytesIO(cldr_file.read()) readFiles(cldr_data) @@ -1435,20 +1438,20 @@ class TzDataFile: def validateTimeZones(zones, links): """ Validate the zone and link entries. """ - linkZones = set(links.viewkeys()) + linkZones = set(six.viewkeys(links)) intersect = linkZones.intersection(zones) if intersect: raise RuntimeError("Links also present in zones: %s" % intersect) zoneNames = set(z.name for z in zones) - linkTargets = set(links.viewvalues()) + linkTargets = set(six.viewvalues(links)) if not linkTargets.issubset(zoneNames): raise RuntimeError("Link targets not found: %s" % linkTargets.difference(zoneNames)) def partition(iterable, *predicates): def innerPartition(pred, it): it1, it2 = tee(it) - return (ifilter(pred, it1), ifilterfalse(pred, it2)) + return (filter(pred, it1), filterfalse(pred, it2)) if len(predicates) == 0: return iterable (left, right) = innerPartition(predicates[0], iterable) @@ -1459,7 +1462,7 @@ def partition(iterable, *predicates): def listIANAFiles(tzdataDir): def isTzFile(d, m, f): return m(f) and d.isfile(d.resolve(f)) - return ifilter(partial(isTzFile, tzdataDir, re.compile("^[a-z0-9]+$").match), tzdataDir.listdir()) + return filter(partial(isTzFile, tzdataDir, re.compile("^[a-z0-9]+$").match), tzdataDir.listdir()) def readIANAFiles(tzdataDir, files): """ Read all IANA time zone files from the given iterable. """ @@ -1507,7 +1510,7 @@ def readIANATimeZones(tzdataDir, ignoreBackzone, ignoreFactory): # Merge with backzone data. if not ignoreBackzone: zones |= backzones - links = {name: target for name, target in links.iteritems() if name not in backzones} + links = {name: target for name, target in links.items() if name not in backzones} links.update(backlinks) validateTimeZones(zones, links) @@ -1644,7 +1647,7 @@ def readICUTimeZonesFromZoneInfo(icuTzDir): elif name == namesKey: tzNames.extend(value) - links = dict((Zone(tzNames[zone]), tzNames[target]) for (zone, target) in tzLinks.iteritems()) + links = dict((Zone(tzNames[zone]), tzNames[target]) for (zone, target) in tzLinks.items()) zones = set([Zone(v) for v in tzNames if Zone(v) not in links]) validateTimeZones(zones, links) @@ -1685,7 +1688,7 @@ def readICUTimeZones(icuDir, icuTzDir, ignoreFactory): if notFoundInZoneInfo64: raise RuntimeError("Missing time zones in zoneinfo64.txt: %s" % notFoundInZoneInfo64) - notFoundInZoneInfo64 = [zone for zone in typesLinks.iterkeys() if not inZoneInfo64(zone)] + notFoundInZoneInfo64 = [zone for zone in typesLinks.keys() if not inZoneInfo64(zone)] if notFoundInZoneInfo64: raise RuntimeError("Missing time zones in zoneinfo64.txt: %s" % notFoundInZoneInfo64) @@ -1697,8 +1700,8 @@ def readICUTimeZones(icuDir, icuTzDir, ignoreFactory): (zone for zone in typesZones) )) icuLinks = dict(chain( - ((zone, target) for (zone, target) in zoneinfoLinks.iteritems() if zone not in typesZones), - ((zone, target) for (zone, target) in typesLinks.iteritems()) + ((zone, target) for (zone, target) in zoneinfoLinks.items() if zone not in typesZones), + ((zone, target) for (zone, target) in typesLinks.items()) )) return (icuZones, icuLinks) @@ -1801,7 +1804,7 @@ def findIncorrectICUZones(ianaZones, ianaLinks, icuZones, icuLinks, ignoreBackzo # Remove unnecessary UTC mappings. utcnames = ["Etc/UTC", "Etc/UCT", "Etc/GMT"] - result = ifilterfalse(lambda (zone, target): zone.name in utcnames, result) + result = filterfalse(lambda zone_target1: zone_target1[0].name in utcnames, result) return sorted(result, key=itemgetter(0)) @@ -1813,28 +1816,28 @@ def findIncorrectICULinks(ianaZones, ianaLinks, icuZones, icuLinks): isICUZone = lambda zone: zone in icuZones # All links should be present in ICU. - missingTimeZones = [zone for zone in ianaLinks.iterkeys() if not isICUTimeZone(zone)] + missingTimeZones = [zone for zone in ianaLinks.keys() if not isICUTimeZone(zone)] if missingTimeZones: raise RuntimeError("Not all zones are present in ICU, did you forget " "to run intl/update-tzdata.sh? %s" % missingTimeZones) # Links which are only present in ICU? - additionalTimeZones = [zone for zone in icuLinks.iterkeys() if not isIANATimeZone(zone)] + additionalTimeZones = [zone for zone in icuLinks.keys() if not isIANATimeZone(zone)] if additionalTimeZones: raise RuntimeError("Additional links present in ICU, did you forget " "to run intl/update-tzdata.sh? %s" % additionalTimeZones) result = chain( # IANA links which have a different target in ICU. - ((zone, target, icuLinks[zone]) for (zone, target) in ianaLinks.iteritems() if isICULink(zone) and target != icuLinks[zone]), + ((zone, target, icuLinks[zone]) for (zone, target) in ianaLinks.items() if isICULink(zone) and target != icuLinks[zone]), # IANA links which are zones in ICU. - ((zone, target, zone.name) for (zone, target) in ianaLinks.iteritems() if isICUZone(zone)) + ((zone, target, zone.name) for (zone, target) in ianaLinks.items() if isICUZone(zone)) ) # Remove unnecessary UTC mappings. utcnames = ["Etc/UTC", "Etc/UCT", "Etc/GMT"] - result = ifilterfalse(lambda (zone, target, icuTarget): target in utcnames and icuTarget in utcnames, result) + result = filterfalse(lambda zone_target_icuTarget: zone_target_icuTarget[1] in utcnames and zone_target_icuTarget[2] in utcnames, result) return sorted(result, key=itemgetter(0)) @@ -1919,16 +1922,16 @@ def processTimeZones(tzdataDir, icuDir, icuTzDir, version, ignoreBackzone, ignor def updateBackzoneLinks(tzdataDir, links): (backzoneZones, backzoneLinks) = readIANAFiles(tzdataDir, ["backzone"]) (stableZones, updatedLinks, updatedZones) = partition( - links.iteritems(), + links.items(), # Link not changed in backzone. - lambda (zone, target): zone not in backzoneLinks and zone not in backzoneZones, + lambda zone_target2: zone_target2[0] not in backzoneLinks and zone_target2[0] not in backzoneZones, # Link has a new target. - lambda (zone, target): zone in backzoneLinks, + lambda zone_target3: zone_target3[0] in backzoneLinks, ) # Keep stable zones and links with updated target. return dict(chain( stableZones, - imap(lambda (zone, target): (zone, backzoneLinks[zone]), updatedLinks) + map(lambda zone_target: (zone_target[0], backzoneLinks[zone_target[0]]), updatedLinks) )) def generateTzDataLinkTestContent(testDir, version, fileName, description, links): @@ -1981,11 +1984,11 @@ def generateTzDataTestBackwardLinks(tzdataDir, version, ignoreBackzone, testDir) testDir, version, "timeZone_backward_links.js", u"// Link names derived from IANA Time Zone Database, backward file.", - links.iteritems() + links.items() ) def generateTzDataTestNotBackwardLinks(tzdataDir, version, ignoreBackzone, testDir): - tzfiles = ifilterfalse({"backward", "backzone"}.__contains__, listIANAFiles(tzdataDir)) + tzfiles = filterfalse({"backward", "backzone"}.__contains__, listIANAFiles(tzdataDir)) (zones, links) = readIANAFiles(tzdataDir, tzfiles) if not ignoreBackzone: @@ -1995,7 +1998,7 @@ def generateTzDataTestNotBackwardLinks(tzdataDir, version, ignoreBackzone, testD testDir, version, "timeZone_notbackward_links.js", u"// Link names derived from IANA Time Zone Database, excluding backward file.", - links.iteritems() + links.items() ) def generateTzDataTestBackzone(tzdataDir, version, ignoreBackzone, testDir): @@ -2056,7 +2059,7 @@ def generateTzDataTestBackzoneLinks(tzdataDir, version, ignoreBackzone, testDir) testDir, version, "timeZone_backzone_links.js", comment + u"// Backzone links derived from IANA Time Zone Database.", - ((zone, target if not ignoreBackzone else links[zone]) for (zone, target) in backlinks.iteritems()) + ((zone, target if not ignoreBackzone else links[zone]) for (zone, target) in backlinks.items()) ) def generateTzDataTests(tzdataDir, version, ignoreBackzone, testDir): @@ -2114,7 +2117,7 @@ def updateTzdata(topsrcdir, args): if tzDir is None: print("Downloading tzdata file...") - with closing(urllib2.urlopen(url)) as tzfile: + with closing(six.moves.urllib.request.urlopen(url)) as tzfile: fname = urlsplit(tzfile.geturl()).path.split("/")[-1] with tempfile.NamedTemporaryFile(suffix=fname) as tztmpfile: print("File stored in %s" % tztmpfile.name) @@ -2146,7 +2149,7 @@ static inline bool Is{0}Type( linear_search_max_length = 4 - needs_binary_search = any(len(replacements.items()) > linear_search_max_length + needs_binary_search = any(len(list(replacements.items())) > linear_search_max_length for replacements in mapping.values()) if needs_binary_search: @@ -2220,7 +2223,7 @@ const char* js::intl::LanguageTag::replace{0}ExtensionType( # Merge duplicate keys. key_aliases = {} - for (key, replacements) in sorted(mapping.items(), key=itemgetter(0)): + for (key, replacements) in sorted(list(mapping.items()), key=itemgetter(0)): hash_key = to_hash_key(replacements) if hash_key not in key_aliases: key_aliases[hash_key] = [] @@ -2228,7 +2231,7 @@ const char* js::intl::LanguageTag::replace{0}ExtensionType( key_aliases[hash_key].append(key) first_key = True - for (key, replacements) in sorted(mapping.items(), key=itemgetter(0)): + for (key, replacements) in sorted(list(mapping.items()), key=itemgetter(0)): hash_key = to_hash_key(replacements) if key in key_aliases[hash_key]: continue @@ -2242,7 +2245,7 @@ const char* js::intl::LanguageTag::replace{0}ExtensionType( {} ({}) {{""".format(if_kind, cond).strip("\n")) first_key = False - replacements = sorted(replacements.items(), key=itemgetter(0)) + replacements = sorted(list(replacements.items()), key=itemgetter(0)) if len(replacements) > linear_search_max_length: types = [t for (t, _) in replacements] diff --git a/js/src/ctypes/libffi/generate-darwin-source-and-headers.py b/js/src/ctypes/libffi/generate-darwin-source-and-headers.py index 964e861d43..b53ce68c9c 100644 --- a/js/src/ctypes/libffi/generate-darwin-source-and-headers.py +++ b/js/src/ctypes/libffi/generate-darwin-source-and-headers.py @@ -194,7 +194,7 @@ def generate_source_and_headers(generate_osx=True, generate_ios=True): build_target(desktop64_platform, platform_headers) mkdir_p('darwin_common/include') - for header_name, tag_tuples in platform_headers.iteritems(): + for header_name, tag_tuples in platform_headers.items(): basename, suffix = os.path.splitext(header_name) with open(os.path.join('darwin_common/include', header_name), 'w') as header: for tag_tuple in tag_tuples: diff --git a/js/src/devtools/automation/autospider.py b/js/src/devtools/automation/autospider.py index 030d8c98d7..0d9366a87d 100755 --- a/js/src/devtools/automation/autospider.py +++ b/js/src/devtools/automation/autospider.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from __future__ import print_function import argparse import json import logging @@ -106,7 +107,7 @@ def set_vars_from_script(script, vars): var, value = m.groups() if var in tograb: env[var] = value - print("Setting %s = %s" % (var, value)) + print(("Setting %s = %s" % (var, value))) if var.startswith("ORIGINAL_"): originals[var[9:]] = value @@ -290,7 +291,7 @@ if not args.nobuild: configure = os.path.join(DIR.js_src, 'configure') if not os.path.exists(configure): shutil.copyfile(configure + ".in", configure) - os.chmod(configure, 0755) + os.chmod(configure, 0o755) # Run configure; make run_command(['sh', '-c', posixpath.join(PDIR.js_src, 'configure') + ' ' + CONFIGURE_ARGS], check=True) @@ -359,11 +360,11 @@ if 'jstests' in test_suites: # FIXME bug 1291449: This would be unnecessary if we could run msan with -mllvm # -msan-keep-going, but in clang 3.8 it causes a hang during compilation. if variant.get('ignore-test-failures'): - print("Ignoring test results %s" % (results,)) + print(("Ignoring test results %s" % (results,))) results = [0] if args.variant in ('tsan', 'msan'): - files = filter(lambda f: f.startswith("sanitize_log."), os.listdir(OUTDIR)) + files = [f for f in os.listdir(OUTDIR) if f.startswith("sanitize_log.")] fullfiles = [os.path.join(OUTDIR, f) for f in files] # Summarize results @@ -384,11 +385,11 @@ if args.variant in ('tsan', 'msan'): summary_filename = os.path.join(env['MOZ_UPLOAD_DIR'], "%s_summary.txt" % args.variant) with open(summary_filename, 'wb') as outfh: for location, count in sites.most_common(): - print >> outfh, "%d %s" % (count, location) - print(open(summary_filename, 'rb').read()) + print("%d %s" % (count, location), file=outfh) + print((open(summary_filename, 'rb').read())) if 'max-errors' in variant: - print("Found %d errors out of %d allowed" % (len(sites), variant['max-errors'])) + print(("Found %d errors out of %d allowed" % (len(sites), variant['max-errors']))) if len(sites) > variant['max-errors']: results.append(1) diff --git a/js/src/devtools/gc/gc-test.py b/js/src/devtools/gc/gc-test.py index dd2097804a..09d78f1293 100644 --- a/js/src/devtools/gc/gc-test.py +++ b/js/src/devtools/gc/gc-test.py @@ -4,6 +4,7 @@ # Works with python2.6 +from __future__ import print_function import datetime, os, re, sys, traceback import math, string, copy, json import subprocess @@ -82,20 +83,20 @@ def run_tests(tests, test_dir): fmt = '%20s: {"TMax": %4.1f, "TAvg": %4.1f, "MMax": %4.1f, "MAvg": %4.1f, "SMax": %4.1f, "SAvg": %4.1f}' if (i != len(tests) - 1): fmt += ',' - print(fmt %(filename_str ,TMax, TAvg, MMax, MAvg, SMax, MAvg)) + print((fmt %(filename_str ,TMax, TAvg, MMax, MAvg, SMax, MAvg))) except KeyboardInterrupt: print('fail') return dict((filename, dict(TMax=TMax, TAvg=TAvg, MMax=MMax, MAvg=MAvg, SMax=SMax, SAvg=SAvg)) - for filename, (TMax, TAvg, MMax, MAvg, SMax, SAvg) in bench_map.iteritems()) + for filename, (TMax, TAvg, MMax, MAvg, SMax, SAvg) in bench_map.items()) def compare(current, baseline): percent_speedups = [] - for key, current_result in current.iteritems(): + for key, current_result in current.items(): try: baseline_result = baseline[key] except KeyError: - print key, 'missing from baseline' + print(key, 'missing from baseline') continue val_getter = itemgetter('TMax', 'TAvg', 'MMax', 'MAvg', 'SMax', 'SAvg') @@ -113,9 +114,9 @@ def compare(current, baseline): result = 'SLOWER: %6.2f > baseline %6.2f (%+6.2f%%) ' % \ (CTAvg, BTAvg, slowdown) percent_speedups.append(slowdown) - print '%30s: %s' % (key, result) + print('%30s: %s' % (key, result)) if percent_speedups: - print 'Average speedup: %.2f%%' % avg(percent_speedups) + print('Average speedup: %.2f%%' % avg(percent_speedups)) if __name__ == '__main__': script_path = os.path.abspath(__file__) @@ -141,7 +142,7 @@ if __name__ == '__main__': test_list = find_tests(test_dir) if not test_list: - print >> sys.stderr, "No tests found matching command line arguments." + print("No tests found matching command line arguments.", file=sys.stderr) sys.exit(0) test_list = [ Test.from_file(tst, name, OPTIONS) for tst, name in test_list ] @@ -153,7 +154,7 @@ if __name__ == '__main__': except OSError: if not os.path.exists(JS): - print >> sys.stderr, "JS shell argument: file does not exist: '%s'"%JS + print("JS shell argument: file does not exist: '%s'"%JS, file=sys.stderr) sys.exit(1) else: raise diff --git a/js/src/devtools/rootAnalysis/analyze.py b/js/src/devtools/rootAnalysis/analyze.py index 69482dab7b..610d41f192 100755 --- a/js/src/devtools/rootAnalysis/analyze.py +++ b/js/src/devtools/rootAnalysis/analyze.py @@ -9,6 +9,7 @@ Runs the static rooting analysis """ +from __future__ import print_function from subprocess import Popen import subprocess import os @@ -61,7 +62,7 @@ def print_command(command, outfile=None, env=None): outputs.append("%s='%s'" % (key, value)) output = ' '.join(outputs) + " " + output - print output + print(output) def generate_hazards(config, outfilename): jobs = [] @@ -150,13 +151,13 @@ def out_indexes(command): def run_job(name, config): cmdspec, outfiles = JOBS[name] - print("Running " + name + " to generate " + str(outfiles)) + print(("Running " + name + " to generate " + str(outfiles))) if hasattr(cmdspec, '__call__'): cmdspec(config, outfiles) else: temp_map = {} cmdspec = fill(cmdspec, config) - if isinstance(outfiles, basestring): + if isinstance(outfiles, str): stdout_filename = '%s.tmp' % name temp_map[stdout_filename] = outfiles if config['verbose']: @@ -188,7 +189,7 @@ def run_job(name, config): try: os.rename(temp, final) except OSError: - print("Error renaming %s -> %s" % (temp, final)) + print(("Error renaming %s -> %s" % (temp, final))) raise config = { 'ANALYSIS_SCRIPTDIR': os.path.dirname(__file__) } @@ -224,9 +225,9 @@ args = parser.parse_args() for default in defaults: try: - execfile(default, config) + exec(compile(open(default, "rb").read(), default, 'exec'), config) if args.verbose: - print("Loaded %s" % default) + print(("Loaded %s" % default)) except: pass @@ -272,14 +273,14 @@ if args.list: for step in steps: command, outfilename = JOBS[step] if outfilename: - print("%s -> %s" % (step, outfilename)) + print(("%s -> %s" % (step, outfilename))) else: print(step) sys.exit(0) for step in steps: command, outfiles = JOBS[step] - if isinstance(outfiles, basestring): + if isinstance(outfiles, str): data[step] = outfiles else: outfile = 0 diff --git a/js/src/devtools/rootAnalysis/explain.py b/js/src/devtools/rootAnalysis/explain.py index dc8b76f5c6..54bcee53a2 100755 --- a/js/src/devtools/rootAnalysis/explain.py +++ b/js/src/devtools/rootAnalysis/explain.py @@ -1,5 +1,6 @@ #!/usr/bin/python +from __future__ import print_function import re import argparse @@ -34,20 +35,20 @@ try: m = re.match(r'^Time: (.*)', line) mm = re.match(r'^Run on:', line) if m or mm: - print >>hazards, line - print >>extra, line - print >>refs, line + print(line, file=hazards) + print(line, file=extra) + print(line, file=refs) continue m = re.match(r'^Function.*has unnecessary root', line) if m: - print >>extra, line + print(line, file=extra) continue m = re.match(r'^Function.*takes unsafe address of unrooted', line) if m: num_refs += 1 - print >>refs, line + print(line, file=refs) continue m = re.match(r"^Function.*has unrooted.*of type.*live across GC call ('?)(.*?)('?) at \S+:\d+$", line) @@ -90,14 +91,14 @@ try: gcHazards = hazardousGCFunctions[gcFunction] if gcFunction in gcExplanations: - print >>hazards, (gcHazards[index] + gcExplanations[gcFunction]) + print((gcHazards[index] + gcExplanations[gcFunction]), file=hazards) else: - print >>hazards, gcHazards[index] + print(gcHazards[index], file=hazards) except IOError as e: - print 'Failed: %s' % str(e) + print('Failed: %s' % str(e)) -print("Wrote %s" % args.hazards) -print("Wrote %s" % args.extra) -print("Wrote %s" % args.refs) -print("Found %d hazards and %d unsafe references" % (num_hazards, num_refs)) +print(("Wrote %s" % args.hazards)) +print(("Wrote %s" % args.extra)) +print(("Wrote %s" % args.refs)) +print(("Found %d hazards and %d unsafe references" % (num_hazards, num_refs))) diff --git a/js/src/devtools/rootAnalysis/run-test.py b/js/src/devtools/rootAnalysis/run-test.py index 3bc9085a0a..fca7dedeeb 100644 --- a/js/src/devtools/rootAnalysis/run-test.py +++ b/js/src/devtools/rootAnalysis/run-test.py @@ -3,6 +3,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import os import site import subprocess @@ -85,5 +86,5 @@ for name in cfg.tests: os.chdir(outdir) subprocess.call(["sh", "-c", "rm *.xdb"]) - execfile(os.path.join(indir, "test.py"), {'test': test, 'equal': equal}) - print("TEST-PASSED: %s" % name) + exec(compile(open(os.path.join(indir, "test.py"), "rb").read(), os.path.join(indir, "test.py"), 'exec'), {'test': test, 'equal': equal}) + print(("TEST-PASSED: %s" % name)) diff --git a/js/src/devtools/rootAnalysis/t/hazards/test.py b/js/src/devtools/rootAnalysis/t/hazards/test.py index 3eb08aa09d..75c7bf720e 100644 --- a/js/src/devtools/rootAnalysis/t/hazards/test.py +++ b/js/src/devtools/rootAnalysis/t/hazards/test.py @@ -1,3 +1,4 @@ +from __future__ import print_function test.compile("source.cpp") test.run_analysis_script('gcTypes') @@ -22,7 +23,7 @@ assert('' in hazmap) # All hazards should be in f() and loopy() assert(hazmap['cell2'].function == 'Cell* f()') -print(len(set(haz.function for haz in hazards))) +print((len(set(haz.function for haz in hazards)))) assert(len(set(haz.function for haz in hazards)) == 2) # Check that the correct GC call is reported for each hazard. (cell3 has a diff --git a/js/src/devtools/rootAnalysis/t/suppression/test.py b/js/src/devtools/rootAnalysis/t/suppression/test.py index 65974cc336..ad33411460 100644 --- a/js/src/devtools/rootAnalysis/t/suppression/test.py +++ b/js/src/devtools/rootAnalysis/t/suppression/test.py @@ -1,3 +1,4 @@ +from __future__ import print_function test.compile("source.cpp") test.run_analysis_script('gcTypes', upto='gcFunctions') @@ -9,9 +10,9 @@ suppressed = test.load_suppressed_functions() # Only one of these is fully suppressed (ie, *always* called within the scope # of an AutoSuppressGC). -assert(len(filter(lambda f: 'suppressedFunction' in f, suppressed)) == 1) -assert(len(filter(lambda f: 'halfSuppressedFunction' in f, suppressed)) == 0) -assert(len(filter(lambda f: 'unsuppressedFunction' in f, suppressed)) == 0) +assert(len([f for f in suppressed if 'suppressedFunction' in f]) == 1) +assert(len([f for f in suppressed if 'halfSuppressedFunction' in f]) == 0) +assert(len([f for f in suppressed if 'unsuppressedFunction' in f]) == 0) # gcFunctions should be the inverse, but we get to rely on unmangled names here. gcFunctions = test.load_gcFunctions() diff --git a/js/src/devtools/rootAnalysis/t/testlib.py b/js/src/devtools/rootAnalysis/t/testlib.py index 438398f1ed..27d34d12f3 100644 --- a/js/src/devtools/rootAnalysis/t/testlib.py +++ b/js/src/devtools/rootAnalysis/t/testlib.py @@ -1,3 +1,4 @@ +from __future__ import print_function import json import os import re @@ -13,7 +14,7 @@ HazardSummary = namedtuple('HazardSummary', ['function', 'variable', 'type', 'GC def equal(got, expected): if got != expected: - print("Got '%s', expected '%s'" % (got, expected)) + print(("Got '%s', expected '%s'" % (got, expected))) def extract_unmangled(func): return func.split('$')[-1] @@ -37,16 +38,16 @@ class Test(object): CXX=self.cfg.cxx, sixgill=self.cfg.sixgill_plugin, options=options) if self.cfg.verbose: - print("Running %s" % cmd) + print(("Running %s" % cmd)) subprocess.check_call(["sh", "-c", cmd]) def load_db_entry(self, dbname, pattern): '''Look up an entry from an XDB database file, 'pattern' may be an exact matching string, or an re pattern object matching a single entry.''' - if not isinstance(pattern, basestring): + if not isinstance(pattern, str): output = subprocess.check_output([self.binpath("xdbkeys"), dbname + ".xdb"]) - matches = filter(lambda _: re.search(pattern, _), output.splitlines()) + matches = [_ for _ in output.splitlines() if re.search(pattern, _)] if len(matches) == 0: raise Exception("entry not found") if len(matches) > 1: @@ -57,7 +58,7 @@ class Test(object): return json.loads(output) def run_analysis_script(self, phase, upto=None): - file("defaults.py", "w").write('''\ + open("defaults.py", "w").write('''\ analysis_scriptdir = '{scriptdir}' sixgill_bin = '{bindir}' '''.format(scriptdir=scriptdir, bindir=self.cfg.sixgill_bin)) @@ -69,7 +70,7 @@ sixgill_bin = '{bindir}' cmd.append("--js=%s" % self.cfg.js) if self.cfg.verbose: cmd.append("--verbose") - print("Running " + " ".join(cmd)) + print(("Running " + " ".join(cmd))) subprocess.check_call(cmd) def computeGCTypes(self): @@ -80,8 +81,8 @@ sixgill_bin = '{bindir}' def load_text_file(self, filename, extract=lambda l: l): fullpath = os.path.join(self.outdir, filename) - values = (extract(line.strip()) for line in file(fullpath)) - return filter(lambda _: _ is not None, values) + values = (extract(line.strip()) for line in open(fullpath)) + return [_ for _ in values if _ is not None] def load_suppressed_functions(self): return set(self.load_text_file("suppressedFunctions.lst")) diff --git a/js/src/frontend/GenerateReservedWords.py b/js/src/frontend/GenerateReservedWords.py index bd698cc5f0..8095a9d4df 100644 --- a/js/src/frontend/GenerateReservedWords.py +++ b/js/src/frontend/GenerateReservedWords.py @@ -80,14 +80,14 @@ def split_list_per_column(reserved_word_list, column): per_column = column_dict.setdefault(word[column], []) per_column.append(item) - return sorted(column_dict.items(), key=lambda (char, word): ord(char)) + return sorted(list(column_dict.items()), key=lambda char_word: ord(char_word[0])) def generate_letter_switch(opt, unprocessed_columns, reserved_word_list, columns=None): assert(len(reserved_word_list) != 0); if not columns: - columns = range(0, unprocessed_columns) + columns = list(range(0, unprocessed_columns)) if len(reserved_word_list) == 1: index, word = reserved_word_list[0] @@ -161,7 +161,7 @@ def split_list_per_length(reserved_word_list): per_length = length_dict.setdefault(len(word), []) per_length.append(item) - return sorted(length_dict.items(), key=lambda (length, word): length) + return sorted(list(length_dict.items()), key=lambda length_word: length_word[0]) def generate_switch(opt, reserved_word_list): assert(len(reserved_word_list) != 0); diff --git a/js/src/gdb/mozilla/ExecutableAllocator.py b/js/src/gdb/mozilla/ExecutableAllocator.py index e1ff812403..4ebe31a49b 100644 --- a/js/src/gdb/mozilla/ExecutableAllocator.py +++ b/js/src/gdb/mozilla/ExecutableAllocator.py @@ -62,7 +62,7 @@ class jsjitExecutableAllocator(object): self.index = self.index + 1 if self.table[cur]['keyHash'] > 1: # table[i]->isLive() return self.table[cur]['mem']['u']['mDummy'].cast(self.entryType) - return self.next() + return next(self) @ptr_pretty_printer("js::jit::ExecutablePool") class jsjitExecutablePool(mozilla.prettyprinters.Pointer): diff --git a/js/src/gdb/mozilla/JSString.py b/js/src/gdb/mozilla/JSString.py index 99d5ce987d..7c60d8e2ac 100644 --- a/js/src/gdb/mozilla/JSString.py +++ b/js/src/gdb/mozilla/JSString.py @@ -3,6 +3,7 @@ import gdb import mozilla.prettyprinters from mozilla.prettyprinters import pretty_printer, ptr_pretty_printer +unichr = chr try: chr(10000) # UPPER RIGHT PENCIL diff --git a/js/src/gdb/mozilla/asmjs.py b/js/src/gdb/mozilla/asmjs.py index 43fac20c73..c6d742abd9 100644 --- a/js/src/gdb/mozilla/asmjs.py +++ b/js/src/gdb/mozilla/asmjs.py @@ -3,6 +3,7 @@ In asm code, out-of-bounds heap accesses cause segfaults, which the engine handles internally. Make GDB ignore them. """ +from __future__ import print_function import gdb SIGSEGV = 11 diff --git a/js/src/gdb/mozilla/autoload.py b/js/src/gdb/mozilla/autoload.py index 43cbcdf721..0acb2dd484 100644 --- a/js/src/gdb/mozilla/autoload.py +++ b/js/src/gdb/mozilla/autoload.py @@ -1,5 +1,6 @@ # mozilla/autoload.py: Autoload SpiderMonkey pretty-printers. +from __future__ import print_function print("Loading JavaScript value pretty-printers; see js/src/gdb/README.") print("If they cause trouble, type: disable pretty-printer .* SpiderMonkey") diff --git a/js/src/gdb/mozilla/unwind.py b/js/src/gdb/mozilla/unwind.py index adea63ea6c..73036a4d6f 100644 --- a/js/src/gdb/mozilla/unwind.py +++ b/js/src/gdb/mozilla/unwind.py @@ -10,14 +10,14 @@ from mozilla.ExecutableAllocator import jsjitExecutableAllocatorCache, jsjitExec # For ease of use in Python 2, we use "long" instead of "int" # everywhere. try: - long + int except NameError: long = int # The Python 3 |map| built-in works lazily, but in Python 2 we need # itertools.imap to get this. try: - from itertools import imap + except ImportError: imap = map @@ -66,7 +66,7 @@ class UnwinderTypeCache(object): return self.d[name] def value(self, name): - return long(gdb.parse_and_eval('js::jit::' + name)) + return int(gdb.parse_and_eval('js::jit::' + name)) def initialize(self): self.d = {} @@ -94,7 +94,7 @@ class UnwinderTypeCache(object): self.d['JSScript'] = gdb.lookup_type("JSScript").pointer() self.d['Value'] = gdb.lookup_type("JS::Value") - self.d['SOURCE_SLOT'] = long(gdb.parse_and_eval('js::ScriptSourceObject::SOURCE_SLOT')) + self.d['SOURCE_SLOT'] = int(gdb.parse_and_eval('js::ScriptSourceObject::SOURCE_SLOT')) self.d['NativeObject'] = gdb.lookup_type("js::NativeObject").pointer() self.d['HeapSlot'] = gdb.lookup_type("js::HeapSlot").pointer() self.d['ScriptSource'] = gdb.lookup_type("js::ScriptSource").pointer() @@ -105,7 +105,7 @@ class UnwinderTypeCache(object): for field in t.fields(): # Strip off "js::jit::". name = field.name[9:] - enumval = long(field.enumval) + enumval = int(field.enumval) self.d[name] = enumval self.frame_enum_names[enumval] = name class_type = gdb.lookup_type('js::jit::' + SizeOfFramePrefix[name]) @@ -134,7 +134,7 @@ def parse_proc_maps(): if name is '' or (name.startswith('[') and name is not '[vdso]'): # Skip entries not corresponding to a file. continue - mappings.append((long(start, 16), long(end, 16))) + mappings.append((int(start, 16), int(end, 16))) return mappings # A symbol/value pair as expected from gdb frame decorators. @@ -159,7 +159,7 @@ class JitFrameDecorator(FrameDecorator): self.cache = cache def _decode_jitframe(self, this_frame): - calleetoken = long(this_frame['calleeToken_']) + calleetoken = int(this_frame['calleeToken_']) tag = calleetoken & 3 calleetoken = calleetoken ^ tag function = None @@ -224,7 +224,7 @@ class JitFrameDecorator(FrameDecorator): return FrameDecorator.frame_args(self) # Construct and return an iterable of all the arguments. result = [] - num_args = long(this_frame["numActualArgs_"]) + num_args = int(this_frame["numActualArgs_"]) # Sometimes we see very large values here, so truncate it to # bypass the damage. if num_args > 10: @@ -263,7 +263,7 @@ class SpiderMonkeyFrameFilter(object): return JitFrameDecorator(frame, info, self.cache) def filter(self, frame_iter): - return imap(self.maybe_wrap_frame, frame_iter) + return map(self.maybe_wrap_frame, frame_iter) # A frame id class, as specified by the gdb unwinder API. class SpiderMonkeyFrameId(object): @@ -306,7 +306,7 @@ class UnwinderState(object): # Otherwise, return None. This is used by the frame filter to # display extra information about the frame. def get_frame(self, frame): - sp = long(frame.read_register(self.SP_REGISTER)) + sp = int(frame.read_register(self.SP_REGISTER)) if sp in self.frame_map: return self.frame_map[sp] return None @@ -315,7 +315,7 @@ class UnwinderState(object): # queried by |self.get_frame|. |sp| is the frame's stack pointer, # and |name| the frame's type as a string, e.g. "JitFrame_Exit". def add_frame(self, sp, name = None, this_frame = None): - self.frame_map[long(sp)] = { "name": name, "this_frame": this_frame } + self.frame_map[int(sp)] = { "name": name, "this_frame": this_frame } # See whether |pc| is claimed by some text mapping. See # |parse_proc_maps| for details on how the decision is made. @@ -362,12 +362,12 @@ class UnwinderState(object): # the size of this frame's header; and |frame_type| is an integer # representing the previous frame's type. def unpack_descriptor(self, common): - value = long(common['descriptor_']) + value = int(common['descriptor_']) local_size = value >> self.typecache.FRAMESIZE_SHIFT header_size = ((value >> self.typecache.FRAME_HEADER_SIZE_SHIFT) & self.typecache.FRAME_HEADER_SIZE_MASK) header_size = header_size * self.typecache.void_starstar.sizeof - frame_type = long(value & self.typecache.FRAMETYPE_MASK) + frame_type = int(value & self.typecache.FRAMETYPE_MASK) if frame_type == self.typecache.JitFrame_Entry: # Trampoline-x64.cpp pushes a JitFrameLayout object, but # the stack pointer is actually adjusted as if a @@ -470,7 +470,7 @@ class UnwinderState(object): # If the jit does not claim this address, bail. GDB defers to our # unwinder by default, but we don't really want that kind of power. - if not self.is_jit_address(long(pc)): + if not self.is_jit_address(int(pc)): return None if self.next_sp is not None: diff --git a/js/src/gdb/run-tests.py b/js/src/gdb/run-tests.py index 1e4f4783b0..b341b9dbc3 100644 --- a/js/src/gdb/run-tests.py +++ b/js/src/gdb/run-tests.py @@ -5,6 +5,7 @@ # run-tests.py -- Python harness for GDB SpiderMonkey support +from __future__ import print_function import os, re, subprocess, sys, traceback from threading import Thread @@ -104,7 +105,7 @@ class Summary(object): if self.failures: - print "tests failed:" + print("tests failed:") for test in self.failures: test.show(sys.stdout) @@ -129,7 +130,7 @@ class Summary(object): sys.exit(1) if self.timeouts: - print "tests timed out:" + print("tests timed out:") for test in self.timeouts: test.show(sys.stdout) @@ -187,7 +188,7 @@ class Test(TaskPool.Task): self.summary.timeout(self) def show_cmd(self, out): - print "Command: ", make_shell_cmd(self.cmd()) + print("Command: ", make_shell_cmd(self.cmd())) def show_output(self, out): if self.stdout: diff --git a/js/src/gdb/taskpool.py b/js/src/gdb/taskpool.py index 8bfcb3a345..7632c99937 100644 --- a/js/src/gdb/taskpool.py +++ b/js/src/gdb/taskpool.py @@ -1,3 +1,4 @@ +from __future__ import print_function import fcntl, os, select, time from subprocess import Popen, PIPE @@ -68,7 +69,7 @@ class TaskPool(object): # Set self.next_pending to the next task that has not yet been executed. def get_next_pending(self): try: - return self.pending.next() + return next(self.pending) except StopIteration: return None @@ -203,17 +204,17 @@ if __name__ == '__main__': def cmd(self): return ['sh', '-c', 'echo out; sleep %d; echo err>&2' % (self.n,)] def onStdout(self, text): - print '%d stdout: %r' % (self.n, text) + print('%d stdout: %r' % (self.n, text)) def onStderr(self, text): - print '%d stderr: %r' % (self.n, text) + print('%d stderr: %r' % (self.n, text)) def onFinished(self, returncode): - print '%d (rc=%d)' % (self.n, returncode) + print('%d (rc=%d)' % (self.n, returncode)) sorted.append(self.n) def onTimeout(self): - print '%d timed out' % (self.n,) + print('%d timed out' % (self.n,)) p = TaskPool([SortableTask(_) for _ in ns], job_limit=len(ns), timeout=timeout) p.run_all() return sorted - print repr(sleep_sort([1,1,2,3,5,8,13,21,34], 15)) + print(repr(sleep_sort([1,1,2,3,5,8,13,21,34], 15))) diff --git a/js/src/gdb/tests/test-unwind.py b/js/src/gdb/tests/test-unwind.py index 6ddf0cd22b..deed741033 100644 --- a/js/src/gdb/tests/test-unwind.py +++ b/js/src/gdb/tests/test-unwind.py @@ -1,5 +1,6 @@ # Test the unwinder and the frame filter. +from __future__ import print_function import platform def do_unwinder_test(): @@ -21,7 +22,7 @@ def do_unwinder_test(): found_outer = False frames = list(gdb.frames.execute_frame_filters(gdb.newest_frame(), 0, -1)) for frame in frames: - print("examining " + frame.function()) + print(("examining " + frame.function())) if first: assert_eq(frame.function().startswith("Something"), True) first = False diff --git a/js/src/jit-test/jit_test.py b/js/src/jit-test/jit_test.py index 084af2d4e5..9411d037cc 100755 --- a/js/src/jit-test/jit_test.py +++ b/js/src/jit-test/jit_test.py @@ -42,7 +42,7 @@ def choose_item(jobs, max_items, display): for i, job in enumerate(jobs, 1): print("{}) {}".format(i, display(job))) - item = raw_input('Which one:\n') + item = input('Which one:\n') try: item = int(item) if item > job_count or item < 1: @@ -319,7 +319,7 @@ def main(argv): except Exception as e: sys.exit(str(e)) else: - tc = job_list.next() + tc = next(job_list) if options.debugger == 'gdb': debug_cmd = ['gdb', '--args'] diff --git a/js/src/jit/arm/gen-double-encoder-table.py b/js/src/jit/arm/gen-double-encoder-table.py index 1a208fdf40..eb40f40d31 100644 --- a/js/src/jit/arm/gen-double-encoder-table.py +++ b/js/src/jit/arm/gen-double-encoder-table.py @@ -10,7 +10,9 @@ modify this file (which is unlikely), you must re-run this script: python gen-double-encode-table.py > $(topsrcdir)/path/to/DoubleEntryTable.tbl """ +from __future__ import print_function import operator +from functools import reduce def rep(bit, count): return reduce(operator.ior, [bit << c for c in range(count)]) @@ -27,6 +29,6 @@ def encodeDouble(value): cdefgh = value & 0x3f return (a << 31) | (B << 30) | (rep(b, 8) << 22) | cdefgh << 16 -print '/* THIS FILE IS AUTOMATICALLY GENERATED BY gen-double-encode-table.py. */' +print('/* THIS FILE IS AUTOMATICALLY GENERATED BY gen-double-encode-table.py. */') for i in range(256): - print ' { 0x%08x, { %d, %d, 0 } },' % (encodeDouble(i), i & 0xf, i >> 4) + print(' { 0x%08x, { %d, %d, 0 } },' % (encodeDouble(i), i & 0xf, i >> 4)) diff --git a/js/src/jsautokw.py b/js/src/jsautokw.py index fa4b872b52..5cef3d1fe7 100644 --- a/js/src/jsautokw.py +++ b/js/src/jsautokw.py @@ -80,14 +80,14 @@ def split_list_per_column(keyword_list, column): per_column = column_dict.setdefault(keyword[column], []) per_column.append(item) - return sorted(column_dict.items(), key=lambda (char, keyword): ord(char)) + return sorted(list(column_dict.items()), key=lambda char_keyword: ord(char_keyword[0])) def generate_letter_switch(opt, unprocessed_columns, keyword_list, columns=None): assert(len(keyword_list) != 0); if not columns: - columns = range(0, unprocessed_columns) + columns = list(range(0, unprocessed_columns)) if len(keyword_list) == 1: index, keyword = keyword_list[0] @@ -161,7 +161,7 @@ def split_list_per_length(keyword_list): per_length = length_dict.setdefault(len(keyword), []) per_length.append(item) - return sorted(length_dict.items(), key=lambda (length, keyword): length) + return sorted(list(length_dict.items()), key=lambda length_keyword: length_keyword[0]) def generate_switch(opt, keyword_list): assert(len(keyword_list) != 0); diff --git a/js/src/tests/compare_bench.py b/js/src/tests/compare_bench.py index cfe9508cd4..012bd3e0ee 100644 --- a/js/src/tests/compare_bench.py +++ b/js/src/tests/compare_bench.py @@ -15,7 +15,7 @@ def avg(seq): def compare(current, baseline): percent_speedups = [] - for key, current_result in current.iteritems(): + for key, current_result in current.items(): try: baseline_result = baseline[key] except KeyError: diff --git a/js/src/tests/ecma_6/String/make-normalize-generateddata-input.py b/js/src/tests/ecma_6/String/make-normalize-generateddata-input.py index c1983dbd18..4373c0e1ae 100644 --- a/js/src/tests/ecma_6/String/make-normalize-generateddata-input.py +++ b/js/src/tests/ecma_6/String/make-normalize-generateddata-input.py @@ -12,7 +12,7 @@ import re, sys sep_pat = re.compile(' +') def to_code_list(codes): - return '[' + ', '.join(map(lambda x: '0x{0}'.format(x), re.split(sep_pat, codes))) + ']' + return '[' + ', '.join(['0x{0}'.format(x) for x in re.split(sep_pat, codes)]) + ']' def convert(dir): ver_pat = re.compile('NormalizationTest-([0-9\.]+)\.txt') diff --git a/js/src/tests/jstests.py b/js/src/tests/jstests.py index 6cd92a5e01..26225fd513 100755 --- a/js/src/tests/jstests.py +++ b/js/src/tests/jstests.py @@ -170,7 +170,7 @@ def parse_args(): op.error('missing JS_SHELL argument') # Valgrind, gdb, and rr are mutually exclusive. - if sum(map(lambda e: 1 if e else 0, [options.valgrind, options.debug, options.rr])) > 1: + if sum([1 if e else 0 for e in [options.valgrind, options.debug, options.rr]]) > 1: op.error("--valgrind, --debug, and --rr are mutually exclusive.") # Fill the debugger field, as needed. diff --git a/js/src/tests/lib/jittests.py b/js/src/tests/lib/jittests.py index 0a1d1537a3..44464fc29e 100755 --- a/js/src/tests/lib/jittests.py +++ b/js/src/tests/lib/jittests.py @@ -13,12 +13,12 @@ from collections import namedtuple import StringIO if sys.platform.startswith('linux') or sys.platform.startswith('darwin'): - from tasks_unix import run_all_tests + from .tasks_unix import run_all_tests else: - from tasks_win import run_all_tests + from .tasks_win import run_all_tests -from progressbar import ProgressBar, NullProgressBar -from results import TestOutput +from .progressbar import ProgressBar, NullProgressBar +from .results import TestOutput TESTS_LIB_DIR = os.path.dirname(os.path.abspath(__file__)) JS_DIR = os.path.dirname(os.path.dirname(TESTS_LIB_DIR)) @@ -567,7 +567,7 @@ def process_test_results(results, num_tests, pb, options): sys.stdout.write(res.err) if options.check_output: - if res.test.path in output_dict.keys(): + if res.test.path in list(output_dict.keys()): if output_dict[res.test.path] != res.out: pb.message("FAIL - OUTPUT DIFFERS {}".format(res.test.relpath_tests)) else: @@ -623,7 +623,7 @@ def get_remote_results(tests, device, prefix, options): from mozdevice import devicemanager try: - for i in xrange(0, options.repeat): + for i in range(0, options.repeat): for test in tests: yield run_test_remote(test, device, prefix, options) except devicemanager.DMError as e: diff --git a/js/src/tests/lib/manifest.py b/js/src/tests/lib/manifest.py index 7079a186f6..f4a18b05ff 100644 --- a/js/src/tests/lib/manifest.py +++ b/js/src/tests/lib/manifest.py @@ -7,7 +7,7 @@ from __future__ import print_function import os, re, sys from subprocess import Popen, PIPE -from tests import RefTestCase +from .tests import RefTestCase def split_path_into_dirs(path): @@ -199,7 +199,7 @@ def _emit_manifest_at(location, relative, test_gen, depth): filename = os.path.join(location, 'jstests.list') manifest = [] numTestFiles = 0 - for k, test_list in manifests.iteritems(): + for k, test_list in manifests.items(): fullpath = os.path.join(location, k) if os.path.isdir(fullpath): manifest.append("include " + k + "/jstests.list") diff --git a/js/src/tests/lib/progressbar.py b/js/src/tests/lib/progressbar.py index da578783df..bdd7369e90 100644 --- a/js/src/tests/lib/progressbar.py +++ b/js/src/tests/lib/progressbar.py @@ -5,9 +5,9 @@ import math import sys if sys.platform.startswith('win'): - from terminal_win import Terminal + from .terminal_win import Terminal else: - from terminal_unix import Terminal + from .terminal_unix import Terminal class NullProgressBar(object): def update(self, current, data): pass diff --git a/js/src/tests/lib/results.py b/js/src/tests/lib/results.py index 451fe5b657..1598789233 100644 --- a/js/src/tests/lib/results.py +++ b/js/src/tests/lib/results.py @@ -1,7 +1,7 @@ from __future__ import print_function import re -from progressbar import NullProgressBar, ProgressBar +from .progressbar import NullProgressBar, ProgressBar import pipes # subprocess.list2cmdline does not properly escape for sh-like shells @@ -131,7 +131,7 @@ class ResultsSink: dev_label = self.LABELS[tup][1] if self.options.check_output: - if output.test.path in self.output_dict.keys(): + if output.test.path in list(self.output_dict.keys()): if self.output_dict[output.test.path] != output: self.counts['FAIL'] += 1 self.print_automation_result( diff --git a/js/src/tests/lib/tasks_unix.py b/js/src/tests/lib/tasks_unix.py index 487c749ee2..433e47d4aa 100644 --- a/js/src/tests/lib/tasks_unix.py +++ b/js/src/tests/lib/tasks_unix.py @@ -2,10 +2,11 @@ # waitpid to dispatch tasks. This avoids several deadlocks that are possible # with fork/exec + threads + Python. +from __future__ import print_function import errno, os, select, sys from datetime import datetime, timedelta -from progressbar import ProgressBar -from results import NullTestOutput, TestOutput, escape_cmdline +from .progressbar import ProgressBar +from .results import NullTestOutput, TestOutput, escape_cmdline class Task(object): def __init__(self, test, prefix, pid, stdout, stderr): @@ -25,7 +26,7 @@ def spawn_test(test, prefix, passthrough, run_skipped, show_cmd): cmd = test.get_command(prefix) if show_cmd: - print(escape_cmdline(cmd)) + print((escape_cmdline(cmd))) if not passthrough: (rout, wout) = os.pipe() @@ -107,7 +108,7 @@ def read_input(tasks, timeout): try: readable, _, _ = select.select(rlist, [], exlist, timeout) except OverflowError as e: - print >> sys.stderr, "timeout value", timeout + print("timeout value", timeout, file=sys.stderr) raise for fd in readable: diff --git a/js/src/tests/lib/tasks_win.py b/js/src/tests/lib/tasks_win.py index a99640abbf..e091775578 100644 --- a/js/src/tests/lib/tasks_win.py +++ b/js/src/tests/lib/tasks_win.py @@ -6,10 +6,10 @@ from __future__ import print_function, unicode_literals, division import subprocess import sys from datetime import datetime, timedelta -from progressbar import ProgressBar -from results import NullTestOutput, TestOutput, escape_cmdline +from .progressbar import ProgressBar +from .results import NullTestOutput, TestOutput, escape_cmdline from threading import Thread -from Queue import Queue, Empty +from queue import Queue, Empty class EndMarker: @@ -22,7 +22,7 @@ class TaskFinishedMarker: def _do_work(qTasks, qResults, qWatch, prefix, run_skipped, timeout, show_cmd): while True: - test = qTasks.get(block=True, timeout=sys.maxint) + test = qTasks.get(block=True, timeout=sys.maxsize) if test is EndMarker: qWatch.put(EndMarker) qResults.put(EndMarker) @@ -73,7 +73,7 @@ def _do_watch(qWatch, timeout): # ignore this. if ex.winerror != 5: raise - fin = qWatch.get(block=True, timeout=sys.maxint) + fin = qWatch.get(block=True, timeout=sys.maxsize) assert fin is TaskFinishedMarker, "invalid finish marker" diff --git a/js/src/tests/lib/tests.py b/js/src/tests/lib/tests.py index 1de56dc1c4..af31f9a7eb 100644 --- a/js/src/tests/lib/tests.py +++ b/js/src/tests/lib/tests.py @@ -3,12 +3,13 @@ # This contains classes that represent an individual test, including # metadata, and know how to run the tests and determine failures. +from __future__ import print_function import datetime, os, sys, time from contextlib import contextmanager from subprocess import Popen, PIPE from threading import Thread -from results import TestOutput +from .results import TestOutput # When run on tbpl, we run each test multiple times with the following # arguments. @@ -43,14 +44,14 @@ JITFLAGS = { def get_jitflags(variant, **kwargs): if variant not in JITFLAGS: - print('Invalid jitflag: "{}"'.format(variant)) + print(('Invalid jitflag: "{}"'.format(variant))) sys.exit(1) if variant == 'none' and 'none' in kwargs: return kwargs['none'] return JITFLAGS[variant] def valid_jitflags(): - return JITFLAGS.keys() + return list(JITFLAGS.keys()) def get_environment_overlay(js_shell): """ diff --git a/js/src/tests/parsemark.py b/js/src/tests/parsemark.py index 5c2fa4a71f..13420fba97 100644 --- a/js/src/tests/parsemark.py +++ b/js/src/tests/parsemark.py @@ -96,7 +96,7 @@ def parsemark(filepaths, fbench, stfu=False): print('Parsemarking {}...'.format(filename)) bench_map[filename] = fbench(filepath) print('{') - for i, (filename, (avg, stddev)) in enumerate(bench_map.iteritems()): + for i, (filename, (avg, stddev)) in enumerate(bench_map.items()): assert '"' not in filename fmt = ' {:30s}: {{"average_ms": {:6.2f}, "stddev_ms": {:6.2f}}}' if i != len(bench_map) - 1: @@ -105,7 +105,7 @@ def parsemark(filepaths, fbench, stfu=False): print(fmt.format(filename_str, avg, stddev)) print('}') return dict((filename, dict(average_ms=avg, stddev_ms=stddev)) - for filename, (avg, stddev) in bench_map.iteritems()) + for filename, (avg, stddev) in bench_map.items()) def main(): diff --git a/js/src/vm/make_opcode_doc.py b/js/src/vm/make_opcode_doc.py index 454d8b8d5e..b30e8ce6f6 100755 --- a/js/src/vm/make_opcode_doc.py +++ b/js/src/vm/make_opcode_doc.py @@ -275,20 +275,18 @@ def print_opcode(opcode): names_template = '{name} [-{nuses}, +{ndefs}]{flags}' opcodes = sorted([opcode] + opcode.group, key=lambda opcode: opcode.name) - names = map(lambda code: names_template.format(name=escape(code.name), + names = [names_template.format(name=escape(code.name), nuses=override(code.nuses, opcode.nuses_override), ndefs=override(code.ndefs, opcode.ndefs_override), - flags=format_flags(code.flags)), - opcodes) + flags=format_flags(code.flags)) for code in opcodes] if len(opcodes) == 1: values = ['{value} (0x{value:02x})'.format(value=opcode.value)] else: values_template = '{name}: {value} (0x{value:02x})' - values = map(lambda code: values_template.format(name=escape(code.name), - value=code.value), - opcodes) + values = [values_template.format(name=escape(code.name), + value=code.value) for code in opcodes] print("""
{names}
diff --git a/js/src/vm/make_unicode.py b/js/src/vm/make_unicode.py index 8568ccb64c..9f96543a4c 100755 --- a/js/src/vm/make_unicode.py +++ b/js/src/vm/make_unicode.py @@ -27,8 +27,10 @@ import os import sys from contextlib import closing from functools import partial -from itertools import chain, groupby, ifilter, imap, izip_longest, tee +from itertools import chain, groupby, tee from operator import is_not, itemgetter +import six +from itertools import zip_longest class codepoint_dict(dict): def name(self, code_point): @@ -103,12 +105,12 @@ def read_unicode_data(unicode_data): reader = csv.reader(unicode_data, delimiter=';') while True: - row = reader.next() + row = next(reader) name = row[1] # We need to expand the UAX #44 4.2.3 Code Point Range if name.startswith('<') and name.endswith('First>'): - next_row = reader.next() + next_row = next(reader) for i in range(int(row[0], 16), int(next_row[0], 16) + 1): row[0] = i @@ -172,7 +174,7 @@ def int_ranges(ints): """ Yields consecutive ranges (inclusive) from integer values. """ (a, b) = tee(sorted(ints)) start = next(b) - for (curr, succ) in izip_longest(a, b): + for (curr, succ) in zip_longest(a, b): if curr + 1 != succ: yield (start, curr) start = succ @@ -527,16 +529,16 @@ def process_special_casing(special_casing, table, index): return upper def ascii(char_dict): - return ifilter(lambda ch: ch <= 0x7f, char_dict.iterkeys()) + return filter(lambda ch: ch <= 0x7f, char_dict.keys()) def latin1(char_dict): - return ifilter(lambda ch: ch <= 0xff, char_dict.iterkeys()) + return filter(lambda ch: ch <= 0xff, char_dict.keys()) def is_empty(iterable): return not any(True for _ in iterable) def is_equals(iter1, iter2): - return all(x == y for (x, y) in izip_longest(iter1, iter2)) + return all(x == y for (x, y) in zip_longest(iter1, iter2)) # Ensure no ASCII characters have special case mappings. assert is_empty(ascii(unconditional_tolower)) @@ -567,28 +569,28 @@ def process_special_casing(special_casing, table, index): assert all(ch != lowerCase(ch) for ch in [0x0130, 0x03A3]) # Ensure Azeri, Lithuanian, and Turkish are the only languages with conditional case mappings. - assert is_equals(["az", "lt", "tr"], sorted(lang_conditional_tolower.iterkeys())) - assert is_equals(["az", "lt", "tr"], sorted(lang_conditional_toupper.iterkeys())) + assert is_equals(["az", "lt", "tr"], sorted(lang_conditional_tolower.keys())) + assert is_equals(["az", "lt", "tr"], sorted(lang_conditional_toupper.keys())) # Maximum case mapping length is three characters. - itervals = lambda d: d.itervalues() - assert max(imap(len, chain( + itervals = lambda d: d.values() + assert max(map(len, chain( itervals(unconditional_tolower), itervals(unconditional_toupper), - imap(itemgetter(0), itervals(conditional_tolower)), - imap(itemgetter(0), itervals(conditional_toupper)), - imap(itemgetter(0), chain.from_iterable(imap(itervals, itervals(lang_conditional_tolower)))), - imap(itemgetter(0), chain.from_iterable(imap(itervals, itervals(lang_conditional_toupper)))), + map(itemgetter(0), itervals(conditional_tolower)), + map(itemgetter(0), itervals(conditional_toupper)), + map(itemgetter(0), chain.from_iterable(map(itervals, itervals(lang_conditional_tolower)))), + map(itemgetter(0), chain.from_iterable(map(itervals, itervals(lang_conditional_toupper)))), ))) <= 3 # Ensure all case mapping contexts are known (see Unicode 9.0, §3.13 Default Case Algorithms). assert set([ 'After_I', 'After_Soft_Dotted', 'Final_Sigma', 'More_Above', 'Not_Before_Dot', - ]).issuperset(set(ifilter(partial(is_not, None), chain( - imap(itemgetter(1), itervals(conditional_tolower)), - imap(itemgetter(1), itervals(conditional_toupper)), - imap(itemgetter(1), chain.from_iterable(imap(itervals, itervals(lang_conditional_tolower)))), - imap(itemgetter(1), chain.from_iterable(imap(itervals, itervals(lang_conditional_toupper)))), + ]).issuperset(set(filter(partial(is_not, None), chain( + map(itemgetter(1), itervals(conditional_tolower)), + map(itemgetter(1), itervals(conditional_toupper)), + map(itemgetter(1), chain.from_iterable(map(itervals, itervals(lang_conditional_tolower)))), + map(itemgetter(1), chain.from_iterable(map(itervals, itervals(lang_conditional_toupper)))), )))) # Special casing for U+00DF (LATIN SMALL LETTER SHARP S). @@ -677,7 +679,7 @@ def write_special_casing_methods(unconditional_toupper, codepoint_table, println lines[-1].append(expr) else: lines.append([expr]) - return ' ||\n{}'.format(spaces).join(imap(lambda t: ' || '.join(t), lines)) + return ' ||\n{}'.format(spaces).join(map(lambda t: ' || '.join(t), lines)) def write_range_accept(parent_list, child_list, depth): """ Accepts the input character if it matches any code unit in |child_list|. """ @@ -732,7 +734,7 @@ def write_special_casing_methods(unconditional_toupper, codepoint_table, println assert unconditional_toupper, "|unconditional_toupper| is not empty" # Sorted list of code units with special upper case mappings. - code_list = sorted(unconditional_toupper.iterkeys()) + code_list = sorted(unconditional_toupper.keys()) # Fail-fast if the input character isn't a special casing character. println(' if ({})'.format(out_range(code_list[0], code_list[-1]))) @@ -787,7 +789,7 @@ def write_special_casing_methods(unconditional_toupper, codepoint_table, println println('{') println(' switch(ch) {') - for (code, converted) in sorted(unconditional_toupper.iteritems(), key=itemgetter(0)): + for (code, converted) in sorted(unconditional_toupper.items(), key=itemgetter(0)): println(' case {}: return {}; // {}'.format(hexlit(code), len(converted), codepoint_table.name(code))) println(' }') @@ -804,7 +806,7 @@ def write_special_casing_methods(unconditional_toupper, codepoint_table, println println('{') println(' switch(ch) {') - for (code, converted) in sorted(unconditional_toupper.iteritems(), key=itemgetter(0)): + for (code, converted) in sorted(unconditional_toupper.items(), key=itemgetter(0)): println(' case {}: // {}'.format(hexlit(code), codepoint_table.name(code))) for ch in converted: println(' elements[(*index)++] = {}; // {}'.format(hexlit(ch), @@ -843,8 +845,8 @@ def make_bmp_mapping_test(version, codepoint_table, unconditional_tolower, uncon (upper, lower, _, _) = entry upper = unconditional_toupper[code] if code in unconditional_toupper else [upper] lower = unconditional_tolower[code] if code in unconditional_tolower else [lower] - println(' ["{}", "{}"], /* {} */'.format("".join(imap(unicodeEsc, upper)), - "".join(imap(unicodeEsc, lower)), + println(' ["{}", "{}"], /* {} */'.format("".join(map(unicodeEsc, upper)), + "".join(map(unicodeEsc, lower)), codepoint_table.name(code))) else: println(' ["{0}", "{0}"],'.format(unicodeEsc(code))) @@ -1072,7 +1074,7 @@ def make_unicode_file(version, println('bool') println('js::unicode::{}(uint32_t codePoint)'.format(name)) println('{') - for (from_code, to_code) in int_ranges(group_set.keys()): + for (from_code, to_code) in int_ranges(list(group_set.keys())): println(' if (codePoint >= 0x{:X} && codePoint <= 0x{:X}) // {} .. {}'.format(from_code, to_code, codepoint_table.name(from_code), @@ -1117,7 +1119,7 @@ def make_unicode_file(version, # If the following assert fails, it means space character is added to # non-BMP area. In that case the following code should be uncommented # and the corresponding code should be added to frontend. - assert len(non_bmp_space_set.keys()) == 0 + assert len(list(non_bmp_space_set.keys())) == 0 write_supplemental_identifier_method('IsIdentifierStartNonBMP', non_bmp_id_start_set, println) @@ -1277,20 +1279,20 @@ def make_irregexp_tables(version, # Latin1 characters which, when case-mapped through # String.prototype.toUpperCase(), canonicalize to a non-Latin1 character. # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize - casemapped_to_nonlatin1 = ifilter(casemaps_to_nonlatin1, xrange(0, MAX_LATIN1 + 1)) + casemapped_to_nonlatin1 = filter(casemaps_to_nonlatin1, range(0, MAX_LATIN1 + 1)) def casemap_closure(ch): upper = to_upper(ch) - return (ch, [c for c in xrange(MAX_LATIN1 + 1, MAX_BMP + 1) if upper == to_upper(c)]) + return (ch, [c for c in range(MAX_LATIN1 + 1, MAX_BMP + 1) if upper == to_upper(c)]) # Mapping from Latin1 characters to the list of case map equivalent # non-Latin1 characters. - casemap_for_latin1 = dict(chain(imap(casemap_closure, casemapped_to_nonlatin1))) + casemap_for_latin1 = dict(chain(map(casemap_closure, casemapped_to_nonlatin1))) # Non-latin1 characters which, when Unicode case-folded, canonicalize to # a Latin1 character. # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize - casefolded_to_latin1 = ifilter(casefolds_to_latin1, xrange(MAX_LATIN1 + 1, MAX_BMP + 1)) + casefolded_to_latin1 = filter(casefolds_to_latin1, range(MAX_LATIN1 + 1, MAX_BMP + 1)) println(' if (unicode) {') for ch in casefolded_to_latin1: @@ -1304,11 +1306,11 @@ def make_irregexp_tables(version, println(' return {};'.format(consequent(casefolded))) println(' }') println('') - for (ch, casemapped_chars) in casemap_for_latin1.iteritems(): + for (ch, casemapped_chars) in casemap_for_latin1.items(): for casemapped in casemapped_chars: println(' // "{}" case maps to "{}".'.format(char_name(casemapped), char_name(ch))) - println(' if ({})'.format(' || '.join(imap(test, casemapped_chars)))) + println(' if ({})'.format(' || '.join(map(test, casemapped_chars)))) println(' return {};'.format(consequent(ch))) println(' return {};'.format(default)) @@ -1345,7 +1347,7 @@ def make_irregexp_tables(version, character_range = partial(write_character_range, println) # Characters in \s, 21.2.2.12 CharacterClassEscape. - space_chars = filter(is_space, xrange(0, MAX_BMP + 1)) + space_chars = list(filter(is_space, range(0, MAX_BMP + 1))) # Characters in \d, 21.2.2.12 CharacterClassEscape. digit_chars = map(ord, string.digits) @@ -1357,10 +1359,10 @@ def make_irregexp_tables(version, # Characters which case-fold to characters in \w. ignorecase_word_chars = (word_chars + - filter(casefolds_to_ascii, xrange(MAX_ASCII + 1, MAX_BMP + 1))) + list(filter(casefolds_to_ascii, range(MAX_ASCII + 1, MAX_BMP + 1)))) # Surrogate characters. - surrogate_chars = range(LEAD_SURROGATE_MIN, TRAIL_SURROGATE_MAX + 1) + surrogate_chars = list(range(LEAD_SURROGATE_MIN, TRAIL_SURROGATE_MAX + 1)) write(warning_message) write(unicode_version_message.format(version)) @@ -1383,7 +1385,7 @@ def make_irregexp_tables(version, character_range('IgnoreCaseWord', ignorecase_word_chars) character_range('WordAndSurrogate', word_chars + surrogate_chars) character_range('NegatedIgnoreCaseWordAndSurrogate', - set(xrange(0, MAX_BMP + 1)) - set(ignorecase_word_chars + surrogate_chars)) + set(range(0, MAX_BMP + 1)) - set(ignorecase_word_chars + surrogate_chars)) character_range('Digit', digit_chars) character_range('DigitAndSurrogate', digit_chars + surrogate_chars) @@ -1393,7 +1395,7 @@ def make_irregexp_tables(version, character_range('LineTerminator', line_terminator) def update_unicode(args): - import urllib2 + import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse version = args.version if version is not None: @@ -1417,7 +1419,7 @@ def update_unicode(args): if version is not None: print('Downloading %s...' % fname) unicode_data_url = '%s/%s' % (url, fname) - with closing(urllib2.urlopen(unicode_data_url)) as reader: + with closing(six.moves.urllib.request.urlopen(unicode_data_url)) as reader: data = reader.read() tfile = io.open(tfile_path, 'w+b') tfile.write(data) diff --git a/layout/generic/frame-graph.py b/layout/generic/frame-graph.py index ac1076b83c..025ada76d5 100644 --- a/layout/generic/frame-graph.py +++ b/layout/generic/frame-graph.py @@ -34,7 +34,7 @@ for line in sys.stdin: sys.stdout.write('digraph g {\n') -for olist in classdict.itervalues(): +for olist in classdict.values(): for line in olist: sys.stdout.write(line) diff --git a/layout/reftests/border-image/gen-refs.py b/layout/reftests/border-image/gen-refs.py index 44a89353d1..8850c75ed5 100644 --- a/layout/reftests/border-image/gen-refs.py +++ b/layout/reftests/border-image/gen-refs.py @@ -27,6 +27,7 @@ # Assumes there is no intrinsic size for the border-image-source, so uses # the size of the border image area. +from __future__ import print_function import sys class Point: @@ -65,7 +66,7 @@ class np: def parse_p(tok): if tok[-2:] == "px": return float(tok[:-2]) - print "Whoops, not a pixel value " + tok + print("Whoops, not a pixel value " + tok) def parse_np(tok): if tok[-2:] == "px": @@ -91,11 +92,11 @@ def parse(filename): if toks[0] == "border-image-repeat:": props.repeat = toks[1] if toks[0] == "border-image-slice:": - props.slice = map(parse_p, toks[1:5]) + props.slice = list(map(parse_p, toks[1:5])) if toks[0] == "border-image-width:": - props.image_width = map(parse_np, toks[1:5]) + props.image_width = list(map(parse_np, toks[1:5])) if toks[0] == "border-image-outset:": - props.outset = map(parse_np, toks[1:5]) + props.outset = list(map(parse_np, toks[1:5])) f.close() return props @@ -106,8 +107,8 @@ def normalise(props): result = Props() result.source = props.source result.repeat = props.repeat - result.width = map(lambda x: x.get_absolute(props.width), props.image_width) - outsets = map(lambda x: x.get_absolute(props.width), props.outset) + result.width = [x.get_absolute(props.width) for x in props.image_width] + outsets = [x.get_absolute(props.width) for x in props.outset] result.size.width = props.size.width + 2*props.width + outsets[1] + outsets[3] result.size.height = props.size.height + 2*props.width + outsets[0] + outsets[2] result.slice = props.slice @@ -121,47 +122,47 @@ def normalise(props): def check_parse(props): if not hasattr(props, 'source'): - print "missing border-image-source" + print("missing border-image-source") return False if not hasattr(props.size, 'width'): - print "missing width" + print("missing width") return False if not hasattr(props.size, 'height'): - print "missing height" + print("missing height") return False if not hasattr(props, 'width'): - print "missing border-width" + print("missing border-width") return False if not hasattr(props, 'image_width'): - print "missing border-image-width" + print("missing border-image-width") return False if not hasattr(props, 'slice'): - print "missing border-image-slice" + print("missing border-image-slice") return False if not hasattr(props, 'repeat') or (props.repeat not in ["stretch", "repeat", "round"]): - print "missing or incorrect border-image-repeat '" + props.repeat + "'" + print("missing or incorrect border-image-repeat '" + props.repeat + "'") return False if not hasattr(props, 'outset'): - print "missing border-image-outset" + print("missing border-image-outset") return False return True def check_normalise(props): if not hasattr(props, 'source'): - print "missing border-image-source" + print("missing border-image-source") return False if not hasattr(props.size, 'width'): - print "missing width" + print("missing width") return False if not hasattr(props.size, 'height'): - print "missing height" + print("missing height") return False if not hasattr(props, 'slice'): - print "missing border-image-slice" + print("missing border-image-slice") return False if not hasattr(props, 'repeat') or (props.repeat not in ["stretch", "repeat", "round"]): - print "missing or incorrect border-image-repeat '" + props.repeat + "'" + print("missing or incorrect border-image-repeat '" + props.repeat + "'") return False return True @@ -180,7 +181,7 @@ class Tile: def make_src_tiles(): tiles = [Tile() for i in range(9)] - rows = [range(3*i, 3*(i+1)) for i in range(3)] + rows = [list(range(3*i, 3*(i+1))) for i in range(3)] cols = [[i, i+3, i+6] for i in range(3)] row_limits_slice = [0, props.slice[3], props.size.width - props.slice[1], props.size.width] @@ -239,7 +240,7 @@ def compute(props): for t in [tiles[i] for i in [3, 4, 5]]: t.scale.y = dest_tile_size.height/t.slice.height() else: - print "Whoops, invalid border-image-repeat value" + print("Whoops, invalid border-image-repeat value") # catch overlapping slices. Its easier to deal with it here than to catch # earlier and have to avoid all the divide by zeroes above @@ -312,34 +313,34 @@ def compute(props): dest_tiles[(i+1)*tiles_h-2].dest_size.width -= diff_h # output the table to simulate the border - print "" + print("
") for i in range(tiles_h): - print "" + print("") for i in range(tiles_v): - print "" + print("") for j in range(tiles_h): width = dest_tiles[i*tiles_h+j].size.width height = dest_tiles[i*tiles_h+j].size.height # catch any tiles with negative widths/heights # this happends when the total of the border-image-slices > borde drawing area if width <= 0 or height <= 0: - print " " + print(" ") else: - print " " - print "" - print "
" + print(" ") + print("") + print("") # start here args = sys.argv[1:] if len(args) == 0: - print "whoops: no source file" + print("whoops: no source file") exit(1) props = parse(args[0]) if not check_parse(props): - print dir(props) + print(dir(props)) exit(1) props = normalise(props) if not check_normalise(props): diff --git a/layout/reftests/fonts/gsubtest/makegsubfonts.py b/layout/reftests/fonts/gsubtest/makegsubfonts.py index a8aedef0f2..e2e7d5db23 100644 --- a/layout/reftests/fonts/gsubtest/makegsubfonts.py +++ b/layout/reftests/fonts/gsubtest/makegsubfonts.py @@ -1,4 +1,5 @@ +from __future__ import print_function import os import textwrap from xml.etree import ElementTree @@ -124,7 +125,7 @@ def makeLookup1(): if table.format == 4: table.cmap[cp] = glyphName else: - raise NotImplementedError, "Unsupported cmap table format: %d" % table.format + raise NotImplementedError("Unsupported cmap table format: %d" % table.format) cp += 1 # tag.fail @@ -145,7 +146,7 @@ def makeLookup1(): if table.format == 4: table.cmap[cp] = glyphName else: - raise NotImplementedError, "Unsupported cmap table format: %d" % table.format + raise NotImplementedError("Unsupported cmap table format: %d" % table.format) # bump this up so that the sequence is the same as the lookup 3 font cp += 3 @@ -171,7 +172,7 @@ def makeLookup1(): script = scriptRecord.Script = Script() defaultLangSys = script.DefaultLangSys = DefaultLangSys() defaultLangSys.FeatureCount = featureCount - defaultLangSys.FeatureIndex = range(defaultLangSys.FeatureCount) + defaultLangSys.FeatureIndex = list(range(defaultLangSys.FeatureCount)) defaultLangSys.ReqFeatureIndex = 65535 defaultLangSys.LookupOrder = None script.LangSysCount = 0 @@ -326,7 +327,7 @@ def makeLookup3(): if table.format == 4: table.cmap[cp] = glyphName else: - raise NotImplementedError, "Unsupported cmap table format: %d" % table.format + raise NotImplementedError("Unsupported cmap table format: %d" % table.format) cp += 1 # tag.alt1,2,3 @@ -347,7 +348,7 @@ def makeLookup3(): if table.format == 4: table.cmap[cp] = glyphName else: - raise NotImplementedError, "Unsupported cmap table format: %d" % table.format + raise NotImplementedError("Unsupported cmap table format: %d" % table.format) cp += 1 # set the glyph order @@ -371,7 +372,7 @@ def makeLookup3(): script = scriptRecord.Script = Script() defaultLangSys = script.DefaultLangSys = DefaultLangSys() defaultLangSys.FeatureCount = featureCount - defaultLangSys.FeatureIndex = range(defaultLangSys.FeatureCount) + defaultLangSys.FeatureIndex = list(range(defaultLangSys.FeatureCount)) defaultLangSys.ReqFeatureIndex = 65535 defaultLangSys.LookupOrder = None script.LangSysCount = 0 @@ -474,13 +475,13 @@ def makeJavascriptData(): # build fonts -print "Making lookup type 1 font..." +print("Making lookup type 1 font...") makeLookup1() -print "Making lookup type 3 font..." +print("Making lookup type 3 font...") makeLookup3() # output javascript data -print "Making javascript data file..." +print("Making javascript data file...") makeJavascriptData() \ No newline at end of file diff --git a/layout/reftests/w3c-css/import-tests.py b/layout/reftests/w3c-css/import-tests.py index 1a631e2bec..bb1db3a8f0 100755 --- a/layout/reftests/w3c-css/import-tests.py +++ b/layout/reftests/w3c-css/import-tests.py @@ -80,7 +80,7 @@ def log_output_of(subprocess): global gLog subprocess.wait() if (subprocess.returncode != 0): - raise StandardError("error while running subprocess") + raise Exception("error while running subprocess") gLog.write(subprocess.stdout.readline().rstrip()) def write_log_header(): @@ -124,7 +124,7 @@ def populate_test_files(): def copy_file(test, srcfile, destname, isSupportFile=False): global gDestPath, gLog, gSrcPath if not srcfile.startswith(gSrcPath): - raise StandardError("Filename " + srcfile + " does not start with " + gSrcPath) + raise Exception("Filename " + srcfile + " does not start with " + gSrcPath) logname = srcfile[len(gSrcPath):] gLog.write("Importing " + to_unix_path_sep(logname) + " to " + to_unix_path_sep(destname) + "\n") @@ -133,7 +133,7 @@ def copy_file(test, srcfile, destname, isSupportFile=False): if not os.path.exists(destdir): os.makedirs(destdir) if os.path.exists(destfile): - raise StandardError("file " + destfile + " already exists") + raise Exception("file " + destfile + " already exists") copy_and_prefix(test, srcfile, destfile, gPrefixedProperties, isSupportFile) def copy_support_files(test, dirname): @@ -216,7 +216,7 @@ def add_test_items(srcname): else: gLog.write("Warning: href attribute found empty in " + srcname + "\n") if len(refs) > 1: - raise StandardError("Need to add code to specify which reference we want to match.") + raise Exception("Need to add code to specify which reference we want to match.") for ref in refs: tests.append(["==", map_file(srcname), map_file(ref)]) for notref in notrefs: @@ -287,7 +287,7 @@ def setup_paths(): gSrcPath = gArgs[0] if not os.path.isdir(gSrcPath) or \ not os.path.isdir(os.path.join(gSrcPath, ".hg")): - raise StandardError("source path does not appear to be a mercurial clone") + raise Exception("source path does not appear to be a mercurial clone") gDestPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "received") newSubtrees = [] @@ -339,7 +339,7 @@ def main(): listfile.write("\ndefault-preferences {0}\n\n".format(defaultPreferences)) lastDefaultPreferences = defaultPreferences key = 1 - while not test[key] in gTestFlags.keys() and key < len(test): + while not test[key] in list(gTestFlags.keys()) and key < len(test): key = key + 1 testType = test[key - 1] testFlags = gTestFlags[test[key]] diff --git a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-line-height-tests.py b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-line-height-tests.py index 7aa975aaa6..ccc8d2923a 100644 --- a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-line-height-tests.py +++ b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-line-height-tests.py @@ -10,6 +10,7 @@ reftest.list to the stdout. from __future__ import unicode_literals +from __future__ import print_function TEST_FILE = 'text-emphasis-line-height-{:03}{}.html' TEST_TEMPLATE = ''' @@ -62,7 +63,7 @@ def write_file(filename, content): with open(filename, 'wb') as f: f.write(content.encode('UTF-8')) -print("# START tests from {}".format(__file__)) +print(("# START tests from {}".format(__file__))) idx = 0 for (pos, emphasis_pos, ruby_pos, wms, dir) in POSITIONS: idx += 1 @@ -78,5 +79,5 @@ for (pos, emphasis_pos, ruby_pos, wms, dir) in POSITIONS: pos=pos, wm=wm, tag=tag, index=idx, dir=dir, start=start.format(style1=style1, style2=STYLE2), end=end) write_file(test_file, content) - print("== {} {}".format(test_file, ref_file)) -print("# END tests from {}".format(__file__)) + print(("== {} {}".format(test_file, ref_file))) +print(("# END tests from {}".format(__file__))) diff --git a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-position-property-tests.py b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-position-property-tests.py index 94701b57f2..f843919ba8 100644 --- a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-position-property-tests.py +++ b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-position-property-tests.py @@ -11,6 +11,7 @@ tests it generated in the format of Mozilla reftest.list to the stdout. from __future__ import unicode_literals +from __future__ import print_function import itertools TEST_FILE = 'text-emphasis-position-property-{:03}{}.html' @@ -72,8 +73,8 @@ for wm in WRITING_MODES: if wm != "horizontal-tb": write_test_files(wm, "sideways", pos1, pos2) -print("# START tests from {}".format(__file__)) +print(("# START tests from {}".format(__file__))) reftest_items.sort() for item in reftest_items: print(item) -print("# END tests from {}".format(__file__)) +print(("# END tests from {}".format(__file__))) diff --git a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-ruby-tests.py b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-ruby-tests.py index bb2f9706ad..4db2584a50 100644 --- a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-ruby-tests.py +++ b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-ruby-tests.py @@ -9,6 +9,7 @@ tests it generated in the format of Mozilla reftest.list to the stdout. from __future__ import unicode_literals +from __future__ import print_function TEST_FILE = 'text-emphasis-ruby-{:03}{}.html' TEST_TEMPLATE = ''' @@ -52,7 +53,7 @@ def write_file(filename, content): with open(filename, 'wb') as f: f.write(content.encode('UTF-8')) -print("# START tests from {}".format(__file__)) +print(("# START tests from {}".format(__file__))) idx = 0 for pos, ref_wm, ruby_pos, subtests in TEST_CASES: idx += 1 @@ -65,5 +66,5 @@ for pos, ref_wm, ruby_pos, subtests in TEST_CASES: test_content = TEST_TEMPLATE.format( wm=wm, pos=pos, index=idx, ruby_pos=ruby_pos, posval=posval) write_file(test_file, test_content) - print("== {} {}".format(test_file, ref_file)) -print("# END tests from {}".format(__file__)) + print(("== {} {}".format(test_file, ref_file))) +print(("# END tests from {}".format(__file__))) diff --git a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-style-property-tests.py b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-style-property-tests.py index eb14e83bc5..9ecc609659 100644 --- a/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-style-property-tests.py +++ b/layout/reftests/w3c-css/submitted/text-decor-3/support/generate-text-emphasis-style-property-tests.py @@ -10,6 +10,7 @@ tests it generated in the format of Mozilla reftest.list to the stdout. from __future__ import unicode_literals +from __future__ import print_function TEST_FILE = 'text-emphasis-style-property-{:03}{}.html' TEST_TEMPLATE = ''' @@ -59,7 +60,7 @@ def write_test_file(idx, suffix, style, code, name=None): char=get_html_entity(code), code='U+{:04X}'.format(code), title=name)) - print("== {} {}".format(filename, REF_FILE.format(idx))) + print(("== {} {}".format(filename, REF_FILE.format(idx)))) idx = 10 def write_files(style, code): @@ -77,9 +78,9 @@ def write_files(style, code): if shape == 'circle': write_test_file(idx, next(suffix), fill, code, fill + ', horizontal') -print("# START tests from {}".format(__file__)) +print(("# START tests from {}".format(__file__))) for name, code, _ in DATA_SET: write_files(('filled', name), code) for name, _, code in DATA_SET: write_files(('open', name), code) -print("# END tests from {}".format(__file__)) +print(("# END tests from {}".format(__file__))) diff --git a/layout/style/GenerateCSSPropsGenerated.py b/layout/style/GenerateCSSPropsGenerated.py index 5038e9afe7..18ab142fe4 100644 --- a/layout/style/GenerateCSSPropsGenerated.py +++ b/layout/style/GenerateCSSPropsGenerated.py @@ -3,6 +3,7 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. import sys +import functools import string import argparse import subprocess @@ -26,7 +27,7 @@ def get_properties(preprocessorHeader): property_order = {"longhand": 0, "logical": 0, "shorthand": 1, "alias": 2} return property_order[x["proptype"]] - property_order[y["proptype"]] - properties = sorted(properties, cmp=property_compare) + properties = sorted(properties, key=functools.cmp_to_key(property_compare)) for i, p in enumerate(properties): p["index"] = i @@ -62,22 +63,22 @@ def generate_assertions(properties): return "eCSSProperty_%s" % p["id"] msg = ('static_assert(%s == %d, "GenerateCSSPropsGenerated.py did not list ' 'properties in nsCSSPropertyID order");') - return "\n".join(map(lambda p: msg % (enum(p), p["index"]), properties)) + return "\n".join([msg % (enum(p), p["index"]) for p in properties]) def generate_idl_name_positions(properties): # Skip aliases. - ps = filter(lambda p: p["proptype"] is not "alias", properties) + ps = [p for p in properties if p["proptype"] is not "alias"] # Sort alphabetically by IDL name. - ps = sorted(ps, key=lambda p: p["idlname"]) + ps = sorted(ps, key=lambda p: (p["idlname"] is None, p["idlname"] or '')) # Annotate entries with the sorted position. ps = [(p, position) for position, p in enumerate(ps)] # Sort back to nsCSSPropertyID order. - ps = sorted(ps, key=lambda (p, position): p["index"]) + ps = sorted(ps, key=lambda p_position1: p_position1[0]["index"]) - return ",\n".join(map(lambda (p, position): " %d" % position, ps)) + return ",\n".join([" %d" % p_position[1] for p_position in ps]) def generate(output, cppTemplate, preprocessorHeader): cppFile = open(cppTemplate, "r") diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index a85181f9a6..871c265e8f 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals +from __future__ import print_function import os import re import sys @@ -149,7 +150,7 @@ class ReftestRunner(MozbuildObject): import runreftestmulet if self.substs.get('ENABLE_MARIONETTE') != '1': - print(MARIONETTE_DISABLED % self.mozconfig['path']) + print((MARIONETTE_DISABLED % self.mozconfig['path'])) return 1 if not args.profile: @@ -161,7 +162,7 @@ class ReftestRunner(MozbuildObject): if os.path.isfile(os.path.join(args.profile, 'extensions', 'httpd@gaiamobile.org')): - print(GAIA_PROFILE_IS_DEBUG % args.profile) + print((GAIA_PROFILE_IS_DEBUG % args.profile)) return 1 args.app = self.get_binary_path() diff --git a/layout/tools/reftest/mach_test_package_commands.py b/layout/tools/reftest/mach_test_package_commands.py index 197800cf27..b35eee8110 100644 --- a/layout/tools/reftest/mach_test_package_commands.py +++ b/layout/tools/reftest/mach_test_package_commands.py @@ -27,7 +27,7 @@ def run_reftest(context, **kwargs): test_root = os.path.join(context.package_root, 'reftest', 'tests') normalize = partial(context.normalize_test_path, test_root) - args.tests = map(normalize, args.tests) + args.tests = list(map(normalize, args.tests)) return run_reftest_desktop(context, args) diff --git a/layout/tools/reftest/reftestcommandline.py b/layout/tools/reftest/reftestcommandline.py index 40bd8a5ee1..5de242df5d 100644 --- a/layout/tools/reftest/reftestcommandline.py +++ b/layout/tools/reftest/reftestcommandline.py @@ -2,7 +2,7 @@ import argparse import os import sys from collections import OrderedDict -from urlparse import urlparse +from urllib.parse import urlparse import mozlog @@ -254,7 +254,7 @@ class ReftestArgumentsParser(argparse.ArgumentParser): return for test_path in options.tests: - for manifest_file, suite in manifests.iteritems(): + for manifest_file, suite in manifests.items(): if os.path.exists(os.path.join(test_path, manifest_file)): options.suite = suite return diff --git a/layout/tools/reftest/remotereftest.py b/layout/tools/reftest/remotereftest.py index f871c75861..170237d1f3 100644 --- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -2,12 +2,13 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import sys import os import time import tempfile import traceback -import urllib2 +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import mozdevice import mozinfo @@ -30,7 +31,7 @@ class RemoteReftestResolver(ReftestResolver): elif os.path.exists(os.path.abspath(path)): rv = os.path.abspath(path) else: - print >> sys.stderr, "Could not find manifest %s" % script_abs_path + print("Could not find manifest %s" % script_abs_path, file=sys.stderr) sys.exit(1) return os.path.normpath(rv) @@ -88,7 +89,7 @@ class ReftestServer: self._process = self.automation.Process([xpcshell] + args, env = env) pid = self._process.pid if pid < 0: - print "TEST-UNEXPECTED-FAIL | remotereftests.py | Error starting server." + print("TEST-UNEXPECTED-FAIL | remotereftests.py | Error starting server.") return 2 self.automation.log.info("INFO | remotereftests.py | Server pid: %d", pid) @@ -108,14 +109,14 @@ class ReftestServer: time.sleep(1) i += 1 else: - print "TEST-UNEXPECTED-FAIL | remotereftests.py | Timed out while waiting for server startup." + print("TEST-UNEXPECTED-FAIL | remotereftests.py | Timed out while waiting for server startup.") self.stop() return 1 def stop(self): if hasattr(self, '_process'): try: - c = urllib2.urlopen(self.shutdownURL) + c = six.moves.urllib.request.urlopen(self.shutdownURL) c.read() c.close() @@ -186,7 +187,7 @@ class RemoteReftest(RefTest): paths = [options.xrePath, localAutomation.DIST_BIN, self.automation._product, os.path.join('..', self.automation._product)] options.xrePath = self.findPath(paths) if options.xrePath == None: - print "ERROR: unable to find xulrunner path for %s, please specify with --xre-path" % (os.name) + print("ERROR: unable to find xulrunner path for %s, please specify with --xre-path" % (os.name)) return 1 paths.append("bin") paths.append(os.path.join("..", "bin")) @@ -199,7 +200,7 @@ class RemoteReftest(RefTest): paths.insert(0, options.utilityPath) options.utilityPath = self.findPath(paths, xpcshell) if options.utilityPath == None: - print "ERROR: unable to find utility path for %s, please specify with --utility-path" % (os.name) + print("ERROR: unable to find utility path for %s, please specify with --utility-path" % (os.name)) return 1 options.serverProfilePath = tempfile.mkdtemp() @@ -244,7 +245,7 @@ class RemoteReftest(RefTest): self._devicemanager.pushDir(profileDir, options.remoteProfile) self._devicemanager.chmodDir(options.remoteProfile) except mozdevice.DMError: - print "Automation Error: Failed to copy profiledir to device" + print("Automation Error: Failed to copy profiledir to device") raise return profile @@ -256,26 +257,26 @@ class RemoteReftest(RefTest): self._devicemanager.pushDir(profileDir, options.remoteProfile) self._devicemanager.chmodDir(options.remoteProfile) except mozdevice.DMError: - print "Automation Error: Failed to copy extra files to device" + print("Automation Error: Failed to copy extra files to device") raise def printDeviceInfo(self, printLogcat=False): try: if printLogcat: logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters) - print ''.join(logcat) - print "Device info:" + print(''.join(logcat)) + print("Device info:") devinfo = self._devicemanager.getInfo() for category in devinfo: if type(devinfo[category]) is list: - print " %s:" % category + print(" %s:" % category) for item in devinfo[category]: - print " %s" % item + print(" %s" % item) else: - print " %s: %s" % (category, devinfo[category]) - print "Test root: %s" % self._devicemanager.deviceRoot + print(" %s: %s" % (category, devinfo[category])) + print("Test root: %s" % self._devicemanager.deviceRoot) except mozdevice.DMError: - print "WARNING: Error getting device information" + print("WARNING: Error getting device information") def environment(self, **kwargs): return self.automation.environment(**kwargs) @@ -308,8 +309,8 @@ class RemoteReftest(RefTest): self._devicemanager.fileExists(self.remoteLogFile): self._devicemanager.getFile(self.remoteLogFile, self.localLogName) else: - print "WARNING: Unable to retrieve log file (%s) from remote " \ - "device" % self.remoteLogFile + print("WARNING: Unable to retrieve log file (%s) from remote " \ + "device" % self.remoteLogFile) self._devicemanager.removeDir(self.remoteProfile) self._devicemanager.removeDir(self.remoteTestRoot) RefTest.cleanup(self, profileDir) @@ -318,12 +319,12 @@ class RemoteReftest(RefTest): os.remove(self.pidFile) os.remove(self.pidFile + ".xpcshell.pid") except: - print "Warning: cleaning up pidfile '%s' was unsuccessful from the test harness" % self.pidFile + print("Warning: cleaning up pidfile '%s' was unsuccessful from the test harness" % self.pidFile) def run_test_harness(parser, options): if options.dm_trans == 'sut' and options.deviceIP == None: - print "Error: If --dm_trans = sut, you must provide a device IP to connect to via the --deviceIP option" + print("Error: If --dm_trans = sut, you must provide a device IP to connect to via the --deviceIP option") return 1 dm_args = { @@ -343,7 +344,7 @@ def run_test_harness(parser, options): dm = dm_cls(**dm_args) except mozdevice.DMError: traceback.print_exc() - print "Automation Error: exception while initializing devicemanager. Most likely the device is not in a testable state." + print("Automation Error: exception while initializing devicemanager. Most likely the device is not in a testable state.") return 1 automation = RemoteAutomation(None) @@ -359,7 +360,7 @@ def run_test_harness(parser, options): expected = options.app.split('/')[-1] installed = dm.shellCheckOutput(['pm', 'list', 'packages', expected]) if expected not in installed: - print "%s is not installed on this device" % expected + print("%s is not installed on this device" % expected) return 1 automation.setAppName(options.app) @@ -369,7 +370,7 @@ def run_test_harness(parser, options): parser.validate(options, reftest) if mozinfo.info['debug']: - print "changing timeout for remote debug reftests from %s to 600 seconds" % options.timeout + print("changing timeout for remote debug reftests from %s to 600 seconds" % options.timeout) options.timeout = 600 # Hack in a symbolic link for jsreftest @@ -394,7 +395,7 @@ def run_test_harness(parser, options): dm.recordLogcat() retVal = reftest.runTests(options.tests, options) except: - print "Automation Error: Exception caught while running tests" + print("Automation Error: Exception caught while running tests") traceback.print_exc() retVal = 1 diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index 7061b16ca5..7ea465d48e 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -6,6 +6,7 @@ Runs the reftest test harness. """ +from __future__ import print_function import collections import json import multiprocessing @@ -37,7 +38,7 @@ from mozscreenshot import printstatus, dump_screen try: from marionette_driver.addons import Addons from marionette_harness import Marionette -except ImportError, e: +except ImportError as e: # Defer ImportError until attempt to use Marionette def reraise(*args, **kwargs): raise(e) @@ -85,12 +86,12 @@ class ReftestThread(threading.Thread): def run(self): with printLock: - print "Starting thread with", self.cmdargs + print("Starting thread with", self.cmdargs) sys.stdout.flush() process = subprocess.Popen(self.cmdargs, stdout=subprocess.PIPE) for chunk in self.chunkForMergedOutput(process.stdout): with printLock: - print chunk, + print(chunk, end=' ') sys.stdout.flush() self.retcode = process.wait() @@ -194,7 +195,7 @@ class ReftestResolver(object): manifests[manifest] = set() manifests[manifest].add(filter_str) - for key in manifests.iterkeys(): + for key in manifests.keys(): if None in manifests[key]: manifests[key] = None else: @@ -303,7 +304,7 @@ class RefTest(object): for v in options.extraPrefs: thispref = v.split('=') if len(thispref) < 2: - print "Error: syntax error in --setpref=" + v + print("Error: syntax error in --setpref=" + v) sys.exit(1) prefs[thispref[0]] = thispref[1].strip() @@ -362,7 +363,7 @@ class RefTest(object): for v in options.environment: ix = v.find("=") if ix <= 0: - print "Error: syntax error in --setenv=" + v + print("Error: syntax error in --setenv=" + v) return None browserEnv[v[:ix]] = v[ix + 1:] @@ -498,11 +499,11 @@ class RefTest(object): threadMatches.group('total') if threadMatches else 0) summaryObj['total'] += amount - print 'REFTEST INFO | Result summary:' + print('REFTEST INFO | Result summary:') for (summaryObj, (text, categories)) in zip(summaryObjects, summaryLines): details = ', '.join(["%d %s" % (summaryObj[attribute], description) for ( attribute, description) in categories]) - print 'REFTEST INFO | ' + text + ': ' + str(summaryObj['total']) + ' (' + details + ')' + print('REFTEST INFO | ' + text + ': ' + str(summaryObj['total']) + ' (' + details + ')') return int(any(t.retcode != 0 for t in threads)) diff --git a/layout/tools/reftest/runreftestb2g.py b/layout/tools/reftest/runreftestb2g.py index 6a6346ece0..5dcba6d420 100644 --- a/layout/tools/reftest/runreftestb2g.py +++ b/layout/tools/reftest/runreftestb2g.py @@ -2,7 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. -import ConfigParser +from __future__ import print_function +import six.moves.configparser import os import sys import tempfile @@ -25,7 +26,7 @@ from marionette_harness import Marionette from mozdevice import DeviceManagerADB, DMError -class ProfileConfigParser(ConfigParser.RawConfigParser): +class ProfileConfigParser(six.moves.configparser.RawConfigParser): """Subclass of RawConfigParser that outputs .ini files in the exact format expected for profiles.ini, which is slightly different than the default format. @@ -36,7 +37,7 @@ class ProfileConfigParser(ConfigParser.RawConfigParser): def write(self, fp): if self._defaults: - fp.write("[%s]\n" % ConfigParser.DEFAULTSECT) + fp.write("[%s]\n" % six.moves.configparser.DEFAULTSECT) for (key, value) in self._defaults.items(): fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") @@ -84,7 +85,7 @@ class B2GRemoteReftest(RefTest): try: self._devicemanager.getFile(self.remoteLogFile, self.localLogName) except: - print "ERROR: We were not able to retrieve the info from %s" % self.remoteLogFile + print("ERROR: We were not able to retrieve the info from %s" % self.remoteLogFile) sys.exit(5) # Delete any bundled extensions @@ -121,7 +122,7 @@ class B2GRemoteReftest(RefTest): os.remove(self.pidFile) os.remove(self.pidFile + ".xpcshell.pid") except: - print "Warning: cleaning up pidfile '%s' was unsuccessful from the test harness" % self.pidFile + print("Warning: cleaning up pidfile '%s' was unsuccessful from the test harness" % self.pidFile) def findPath(self, paths, filename = None): for path in paths: @@ -158,7 +159,7 @@ class B2GRemoteReftest(RefTest): os.path.join('..', self.automation._product)] options.xrePath = self.findPath(paths) if options.xrePath == None: - print "ERROR: unable to find xulrunner path for %s, please specify with --xre-path" % (os.name) + print("ERROR: unable to find xulrunner path for %s, please specify with --xre-path" % (os.name)) sys.exit(1) paths.append("bin") paths.append(os.path.join("..", "bin")) @@ -169,7 +170,7 @@ class B2GRemoteReftest(RefTest): options.utilityPath = self.findPath(paths, xpcshell) if options.utilityPath == None: - print "ERROR: unable to find utility path for %s, please specify with --utility-path" % (os.name) + print("ERROR: unable to find utility path for %s, please specify with --utility-path" % (os.name)) sys.exit(1) xpcshell = os.path.join(options.utilityPath, xpcshell) @@ -269,7 +270,7 @@ class B2GRemoteReftest(RefTest): try: self._devicemanager.pushDir(profileDir, self.remoteProfile) except DMError: - print "Automation Error: Unable to copy profile to device." + print("Automation Error: Unable to copy profile to device.") raise # Copy the extensions to the B2G bundles dir. @@ -282,7 +283,7 @@ class B2GRemoteReftest(RefTest): try: self._devicemanager.pushDir(extensionDir, self.bundlesDir) except DMError: - print "Automation Error: Unable to copy extensions to device." + print("Automation Error: Unable to copy extensions to device.") raise self.updateProfilesIni(self.remoteProfile) @@ -296,7 +297,7 @@ class B2GRemoteReftest(RefTest): try: self._devicemanager.pushDir(profileDir, options.remoteProfile) except DMError: - print "Automation Error: Failed to copy extra files to device" + print("Automation Error: Failed to copy extra files to device") raise def environment(self, **kwargs): @@ -375,7 +376,7 @@ def run_test_harness(parser, options): width = int(parts[0].split(':')[1]) height = int(parts[1].split(':')[1]) if (width < 1366 or height < 1050): - print "ERROR: Invalid screen resolution %sx%s, please adjust to 1366x1050 or higher" % (width, height) + print("ERROR: Invalid screen resolution %sx%s, please adjust to 1366x1050 or higher" % (width, height)) return 1 auto.setProduct("b2g") @@ -406,7 +407,7 @@ def run_test_harness(parser, options): retVal = reftest.runTests(options.tests, options) except: - print "Automation Error: Exception caught while running tests" + print("Automation Error: Exception caught while running tests") traceback.print_exc() reftest.stopWebServer(options) try: diff --git a/mach b/mach index 1759179a33..93efcbee5f 100755 --- a/mach +++ b/mach @@ -22,12 +22,13 @@ def ancestors(path): break def load_mach(dir_path, mach_path): - import imp - with open(mach_path, 'r') as fh: - imp.load_module('mach_bootstrap', fh, mach_path, - ('.py', 'r', imp.PY_SOURCE)) - import mach_bootstrap - return mach_bootstrap.bootstrap(dir_path) + import importlib.util + spec = importlib.util.spec_from_file_location('mach_bootstrap', mach_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + import sys + sys.modules['mach_bootstrap'] = module + return module.bootstrap(dir_path) def check_and_get_mach(dir_path): @@ -59,7 +60,7 @@ def get_mach(): # its default locations. # # Note: subprocess requires native strings in os.environ on Windows - os.environ[b'MOZCONFIG'] = str(info['mozconfig']) + os.environ['MOZCONFIG'] = str(info['mozconfig']) if 'topsrcdir' in info: # Continue searching for mach_bootstrap in the source directory. diff --git a/mailnews/extensions/fts3/data/generate_table.py b/mailnews/extensions/fts3/data/generate_table.py index f6b0126856..3a2b0eeef5 100644 --- a/mailnews/extensions/fts3/data/generate_table.py +++ b/mailnews/extensions/fts3/data/generate_table.py @@ -36,18 +36,19 @@ # # ***** END LICENSE BLOCK ***** +from __future__ import print_function import re def printTable(f, t): i = f while i <= t: c = array[i] - print "0x%04x," % c, + print("0x%04x," % c, end=' ') i = i + 1 if not i % 8: - print "\n\t", + print("\n\t", end=' ') -print '''/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +print('''/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -86,7 +87,7 @@ print '''/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: * ***** END LICENSE BLOCK ***** */ /* THIS FILE IS GENERATED BY generate_table.py. DON'T EDIT THIS */ -''' +''') p = re.compile('([0-9A-F]{4,5})(?:\.\.([0-9A-F]{4,5}))?[=\>]([0-9A-F]{4,5})?') G_FROM = 1 @@ -224,10 +225,10 @@ while i < maxmapping: continue if needTerm: - print "};\n" + print("};\n") globalTable.append("gNormalizeTable%04x" % i) - print "static const unsigned short gNormalizeTable%04x[] = {\n\t" % i, - print "/* U+%04x */\n\t" % i, + print("static const unsigned short gNormalizeTable%04x[] = {\n\t" % i, end=' ') + print("/* U+%04x */\n\t" % i, end=' ') needTerm = True # Decomposition does not case-fold, so we want to compensate by # performing a lookup here. Because decomposition chains can be @@ -239,20 +240,20 @@ while i < maxmapping: if c >= 0x41 and c <= 0x5a: raise Exception('got an uppercase character somehow: %x => %x' % (i, c)) - print "0x%04x," % c, + print("0x%04x," % c, end=' ') i = i + 1 if not i % 8: - print "\n\t", + print("\n\t", end=' ') -print "};\n\nstatic const unsigned short* gNormalizeTable[] = {", +print("};\n\nstatic const unsigned short* gNormalizeTable[] = {", end=' ') i = 0 while i < (maxmapping / sizePerTable): if not i % 4: - print "\n\t", - print globalTable[i] + ",", + print("\n\t", end=' ') + print(globalTable[i] + ",", end=' ') i += 1 -print ''' +print(''' }; unsigned int normalize_character(const unsigned int c) @@ -261,4 +262,4 @@ unsigned int normalize_character(const unsigned int c) return c; return gNormalizeTable[c >> 6][c & 0x3f]; } -''' +''') diff --git a/media/libaom/cmakeparser.py b/media/libaom/cmakeparser.py index cb2686a618..b54785de90 100644 --- a/media/libaom/cmakeparser.py +++ b/media/libaom/cmakeparser.py @@ -1,6 +1,7 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function from pyparsing import (CharsNotIn, Group, Forward, Literal, Suppress, Word, QuotedString, ZeroOrMore, alphas, alphanums) from string import Template @@ -36,8 +37,8 @@ def match_block(command, parsed, start): depth -= 1 end = end + 1 if end == len(parsed): - print('error: eof when trying to match block statement: %s' - % parsed[start]) + print(('error: eof when trying to match block statement: %s' + % parsed[start])) return end @@ -67,8 +68,8 @@ def parse_if(parsed, start): depth -= 1 end = end + 1 if end == len(parsed): - print('error: eof when trying to match if statement: %s' - % parsed[start]) + print(('error: eof when trying to match if statement: %s' + % parsed[start])) condition.append(parsed[start:end]) conditions.append(condition) return end, conditions @@ -125,17 +126,17 @@ def evaluate(variables, cache_variables, parsed): elif command == 'include': if arguments: try: - print('including: %s' % arguments[0]) + print(('including: %s' % arguments[0])) sources.extend(parse(variables, cache_variables, arguments[0])) except IOError: - print('warning: could not include: %s' % arguments[0]) + print(('warning: could not include: %s' % arguments[0])) elif command == 'list': try: action = arguments[0] variable = arguments[1] values = arguments[2:] if action == 'APPEND': - if not variables.has_key(variable): + if variable not in variables: variables[variable] = ' '.join(values) else: variables[variable] += ' ' + ' '.join(values) @@ -145,7 +146,7 @@ def evaluate(variables, cache_variables, parsed): variable = arguments[0] value = arguments[2] # Allow options to be override without changing CMake files - if not variables.has_key(variable): + if variable not in variables: variables[variable] = value elif command == 'return': return False, sources @@ -156,7 +157,7 @@ def evaluate(variables, cache_variables, parsed): try: cache = values.index('CACHE') values = values[0:cache] - if not variables.has_key(variable): + if variable not in variables: variables[variable] = ' '.join(values) cache_variables.append(variable) except ValueError: @@ -193,7 +194,7 @@ def evaluate(variables, cache_variables, parsed): for source in arguments[1:]: sources.extend(source.split(' ')) elif command == 'MOZDEBUG': - print('>>>> MOZDEBUG: %s' % ' '.join(arguments)) + print(('>>>> MOZDEBUG: %s' % ' '.join(arguments))) i += 1 return True, sources diff --git a/media/libaom/generate_sources_mozbuild.py b/media/libaom/generate_sources_mozbuild.py index b8ed07b1f7..ef3c088d5a 100644 --- a/media/libaom/generate_sources_mozbuild.py +++ b/media/libaom/generate_sources_mozbuild.py @@ -1,6 +1,7 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import cmakeparser as cp import copy @@ -97,7 +98,7 @@ if __name__ == '__main__': ('x86_64', 'win', 'mingw64', False), ] for cpu, system, arch, generate_sources in platforms: - print('Running CMake for %s (%s)' % (cpu, system)) + print(('Running CMake for %s (%s)' % (cpu, system))) variables = shared_variables.copy() variables['AOM_TARGET_CPU'] = cpu @@ -123,23 +124,23 @@ if __name__ == '__main__': # have to generate sources for each combination. if generate_sources: # Remove spurious sources and perl files - sources = filter(lambda x: x.startswith(AOM_DIR), sources) - sources = filter(lambda x: not x.endswith('.pl'), sources) + sources = [x for x in sources if x.startswith(AOM_DIR)] + sources = [x for x in sources if not x.endswith('.pl')] # Filter out exports - exports = filter(lambda x: re.match(os.path.join(AOM_DIR, '(aom|aom_mem|aom_ports|aom_scale)/.*h$'), x), sources) - exports = filter(lambda x: not re.search('(internal|src)', x), exports) - exports = filter(lambda x: not re.search('(emmintrin_compat.h|mem_.*|msvc.h|aom_once.h)$', x), exports) + exports = [x for x in sources if re.match(os.path.join(AOM_DIR, '(aom|aom_mem|aom_ports|aom_scale)/.*h$'), x)] + exports = [x for x in exports if not re.search('(internal|src)', x)] + exports = [x for x in exports if not re.search('(emmintrin_compat.h|mem_.*|msvc.h|aom_once.h)$', x)] for export in exports: sources.remove(export) # Remove header files - sources = sorted(filter(lambda x: not x.endswith('.h'), sources)) + sources = sorted([x for x in sources if not x.endswith('.h')]) # The build system is unhappy if two files have the same prefix # In libaom, sometimes .asm and .c files share the same prefix - for i in xrange(len(sources) - 1): + for i in range(len(sources) - 1): if sources[i].endswith('.asm'): if os.path.splitext(sources[i])[0] == os.path.splitext(sources[i + 1])[0]: old = sources[i] diff --git a/media/libaom/src/test/gviz_api.py b/media/libaom/src/test/gviz_api.py index d3a443dabf..eb0092264f 100755 --- a/media/libaom/src/test/gviz_api.py +++ b/media/libaom/src/test/gviz_api.py @@ -213,7 +213,7 @@ class DataTable(object): (len(value) == 3 and not isinstance(value[2], dict))): raise DataTableException("Wrong format for value and formatting - %s." % str(value)) - if not isinstance(value[1], types.StringTypes + (types.NoneType,)): + if not isinstance(value[1], (str,) + (type(None),)): raise DataTableException("Formatted value is not string, given %s." % type(value[1])) js_value = DataTable.CoerceValue(value[0], value_type) @@ -226,12 +226,12 @@ class DataTable(object): return bool(value) elif value_type == "number": - if isinstance(value, (int, long, float)): + if isinstance(value, (int, int, float)): return value raise DataTableException("Wrong type %s when expected number" % t_value) elif value_type == "string": - if isinstance(value, unicode): + if isinstance(value, str): return value else: return str(value).decode("utf-8") @@ -296,7 +296,7 @@ class DataTable(object): datetime.date, datetime.time)): return str(value) - elif isinstance(value, unicode): + elif isinstance(value, str): return value elif isinstance(value, bool): return str(value).lower() @@ -329,17 +329,17 @@ class DataTable(object): if not description: raise DataTableException("Description error: empty description given") - if not isinstance(description, (types.StringTypes, tuple)): + if not isinstance(description, ((str,), tuple)): raise DataTableException("Description error: expected either string or " "tuple, got %s." % type(description)) - if isinstance(description, types.StringTypes): + if isinstance(description, (str,)): description = (description,) # According to the tuple's length, we fill the keys # We verify everything is of type string for elem in description[:3]: - if not isinstance(elem, types.StringTypes): + if not isinstance(elem, (str,)): raise DataTableException("Description error: expected tuple of " "strings, current element of type %s." % type(elem)) @@ -456,7 +456,7 @@ class DataTable(object): -- second 'b' is the label, and {} is the custom properties field. """ # For the recursion step, we check for a scalar object (string or tuple) - if isinstance(table_description, (types.StringTypes, tuple)): + if isinstance(table_description, ((str,), tuple)): parsed_col = DataTable.ColumnTypeParser(table_description) parsed_col["depth"] = depth parsed_col["container"] = "scalar" @@ -491,9 +491,9 @@ class DataTable(object): # dictionary). # NOTE: this way of differentiating might create ambiguity. See docs. if (len(table_description) != 1 or - (isinstance(table_description.keys()[0], types.StringTypes) and - isinstance(table_description.values()[0], tuple) and - len(table_description.values()[0]) < 4)): + (isinstance(list(table_description.keys())[0], (str,)) and + isinstance(list(table_description.values())[0], tuple) and + len(list(table_description.values())[0]) < 4)): # This is the most inner dictionary. Parsing types. columns = [] # We sort the items, equivalent to sort the keys since they are unique @@ -509,11 +509,11 @@ class DataTable(object): columns.append(parsed_col) return columns # This is an outer dictionary, must have at most one key. - parsed_col = DataTable.ColumnTypeParser(table_description.keys()[0]) + parsed_col = DataTable.ColumnTypeParser(list(table_description.keys())[0]) parsed_col["depth"] = depth parsed_col["container"] = "dict" return ([parsed_col] + - DataTable.TableDescriptionParser(table_description.values()[0], + DataTable.TableDescriptionParser(list(table_description.values())[0], depth=depth + 1)) @property @@ -622,7 +622,7 @@ class DataTable(object): return # We have a dictionary in an inner depth level. - if not data.keys(): + if not list(data.keys()): # In case this is an empty dictionary, we add a record with the columns # filled only until this point. self.__data.append(prev_col_values) @@ -655,12 +655,12 @@ class DataTable(object): return self.__data proper_sort_keys = [] - if isinstance(order_by, types.StringTypes) or ( + if isinstance(order_by, (str,)) or ( isinstance(order_by, tuple) and len(order_by) == 2 and order_by[1].lower() in ["asc", "desc"]): order_by = (order_by,) for key in order_by: - if isinstance(key, types.StringTypes): + if isinstance(key, (str,)): proper_sort_keys.append((key, 1)) elif (isinstance(key, (list, tuple)) and len(key) == 2 and key[1].lower() in ("asc", "desc")): diff --git a/media/libaom/src/test/visual_metrics.py b/media/libaom/src/test/visual_metrics.py index 9055feb334..4a8cb6a650 100755 --- a/media/libaom/src/test/visual_metrics.py +++ b/media/libaom/src/test/visual_metrics.py @@ -13,6 +13,7 @@ """Converts video encoding result data from text files to visualization data source.""" +from __future__ import print_function __author__ = "jzern@google.com (James Zern)," __author__ += "jimbankoski@google.com (Jim Bankoski)" @@ -457,10 +458,10 @@ def HandleFiles(variables): for i in range(len(dirs)): formatters = "%s formatter.format(better, %d);" % (formatters, i+1) - print FillForm(page_template, vars()) + print(FillForm(page_template, vars())) return if len(sys.argv) < 3: - print HandleFiles.__doc__ + print(HandleFiles.__doc__) else: HandleFiles(sys.argv) diff --git a/media/libaom/src/tools/aggregate_entropy_stats.py b/media/libaom/src/tools/aggregate_entropy_stats.py index 7cb4d18e18..ac61dbe0f5 100644 --- a/media/libaom/src/tools/aggregate_entropy_stats.py +++ b/media/libaom/src/tools/aggregate_entropy_stats.py @@ -14,6 +14,7 @@ python ./aggregate_entropy_stats.py [dir of stats files] [keyword of filenames] [filename of final stats] """ +from __future__ import print_function __author__ = "yuec@google.com" import os diff --git a/media/libaom/src/tools/cpplint.py b/media/libaom/src/tools/cpplint.py index e3ebde2f5a..1ff0053cb3 100755 --- a/media/libaom/src/tools/cpplint.py +++ b/media/libaom/src/tools/cpplint.py @@ -512,7 +512,7 @@ _ALT_TOKEN_REPLACEMENT = { # False positives include C-style multi-line comments and multi-line strings # but those have always been troublesome for cpplint. _ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( - r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') + r'[ =()](' + ('|'.join(list(_ALT_TOKEN_REPLACEMENT.keys()))) + r')(?=[ (]|$)') # These constants define types of headers for use with @@ -952,7 +952,7 @@ class _CppLintState(object): def PrintErrorCounts(self): """Print a summary of errors by category, and the total.""" - for category, count in self.errors_by_category.iteritems(): + for category, count in self.errors_by_category.items(): sys.stderr.write('Category \'%s\' errors found: %d\n' % (category, count)) sys.stdout.write('Total errors found: %d\n' % self.error_count) @@ -1529,7 +1529,7 @@ def FindEndOfExpressionInLine(line, startpos, stack): On finding an unclosed expression: (-1, None) Otherwise: (-1, new stack at end of this line) """ - for i in xrange(startpos, len(line)): + for i in range(startpos, len(line)): char = line[i] if char in '([{': # Found start of parenthesized expression, push to expression stack @@ -1758,7 +1758,7 @@ def CheckForCopyright(filename, lines, error): # We'll say it should occur by line 10. Don't forget there's a # placeholder line at the front. - for line in xrange(1, min(len(lines), 11)): + for line in range(1, min(len(lines), 11)): if re.search(r'Copyright', lines[line], re.I): break else: # means no copyright line was found error(filename, 0, 'legal/copyright', 5, @@ -1960,7 +1960,7 @@ def CheckForHeaderGuard(filename, clean_lines, error): # contain any "//" comments at all, it could be that the compiler # only wants "/**/" comments, look for those instead. no_single_line_comments = True - for i in xrange(1, len(raw_lines) - 1): + for i in range(1, len(raw_lines) - 1): line = raw_lines[i] if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): no_single_line_comments = False @@ -2301,7 +2301,7 @@ class _ClassInfo(_BlockInfo): # If there is a DISALLOW macro, it should appear near the end of # the class. seen_last_thing_in_class = False - for i in xrange(linenum - 1, self.starting_linenum, -1): + for i in range(linenum - 1, self.starting_linenum, -1): match = Search( r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + self.name + r'\)', @@ -3083,7 +3083,7 @@ def CheckForFunctionLengths(filename, clean_lines, linenum, if starting_func: body_found = False - for start_linenum in xrange(linenum, clean_lines.NumLines()): + for start_linenum in range(linenum, clean_lines.NumLines()): start_line = lines[start_linenum] joined_line += ' ' + start_line.lstrip() if Search(r'(;|})', start_line): # Declarations and trivial functions @@ -3540,7 +3540,7 @@ def _IsType(clean_lines, nesting_state, expr): continue # Look for typename in the specified range - for i in xrange(first_line, last_line + 1, 1): + for i in range(first_line, last_line + 1, 1): if Search(typename_pattern, clean_lines.elided[i]): return True block_index -= 1 @@ -3604,7 +3604,7 @@ def CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error): trailing_text = '' if endpos > -1: trailing_text = endline[endpos:] - for offset in xrange(endlinenum + 1, + for offset in range(endlinenum + 1, min(endlinenum + 3, clean_lines.NumLines() - 1)): trailing_text += clean_lines.elided[offset] # We also suppress warnings for `uint64_t{expression}` etc., as the style @@ -4158,7 +4158,7 @@ def CheckCheck(filename, clean_lines, linenum, error): expression = lines[linenum][start_pos + 1:end_pos - 1] else: expression = lines[linenum][start_pos + 1:] - for i in xrange(linenum + 1, end_line): + for i in range(linenum + 1, end_line): expression += lines[i] expression += last_line[0:end_pos - 1] @@ -4286,7 +4286,7 @@ def GetLineWidth(line): The width of the line in column positions, accounting for Unicode combining characters and wide characters. """ - if isinstance(line, unicode): + if isinstance(line, str): width = 0 for uc in unicodedata.normalize('NFC', line): if unicodedata.east_asian_width(uc) in ('W', 'F'): @@ -4622,7 +4622,7 @@ def _GetTextInside(text, start_pattern): # Give opening punctuations to get the matching close-punctuations. matching_punctuation = {'(': ')', '{': '}', '[': ']'} - closing_punctuation = set(matching_punctuation.itervalues()) + closing_punctuation = set(matching_punctuation.values()) # Find the position to start extracting text. match = re.search(start_pattern, text, re.M) @@ -4941,7 +4941,7 @@ def IsDerivedFunction(clean_lines, linenum): virt-specifier. """ # Scan back a few lines for start of current function - for i in xrange(linenum, max(-1, linenum - 10), -1): + for i in range(linenum, max(-1, linenum - 10), -1): match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) if match: # Look for "override" after the matching closing parenthesis @@ -4962,7 +4962,7 @@ def IsOutOfLineMethodDefinition(clean_lines, linenum): True if current line contains an out-of-line method definition. """ # Scan back a few lines for start of current function - for i in xrange(linenum, max(-1, linenum - 10), -1): + for i in range(linenum, max(-1, linenum - 10), -1): if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]): return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None return False @@ -4978,7 +4978,7 @@ def IsInitializerList(clean_lines, linenum): True if current line appears to be inside constructor initializer list, False otherwise. """ - for i in xrange(linenum, 1, -1): + for i in range(linenum, 1, -1): line = clean_lines.elided[i] if i == linenum: remove_function_body = Match(r'^(.*)\{\s*$', line) @@ -5079,7 +5079,7 @@ def CheckForNonConstReference(filename, clean_lines, linenum, # Found the matching < on an earlier line, collect all # pieces up to current line. line = '' - for i in xrange(startline, linenum + 1): + for i in range(startline, linenum + 1): line += clean_lines.elided[i].strip() # Check for non-const references in function parameters. A single '&' may @@ -5103,7 +5103,7 @@ def CheckForNonConstReference(filename, clean_lines, linenum, # appear inside the second set of parentheses on the current line as # opposed to the first set. if linenum > 0: - for i in xrange(linenum - 1, max(0, linenum - 10), -1): + for i in range(linenum - 1, max(0, linenum - 10), -1): previous_line = clean_lines.elided[i] if not Search(r'[),]\s*$', previous_line): break @@ -5134,7 +5134,7 @@ def CheckForNonConstReference(filename, clean_lines, linenum, # Don't see an allowed function on this line. Actually we # didn't see any function name on this line, so this is likely a # multi-line parameter list. Try a bit harder to catch this case. - for i in xrange(2): + for i in range(2): if (linenum > i and Search(allowed_functions, clean_lines.elided[linenum - i - 1])): return @@ -5297,7 +5297,7 @@ def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): # Try expanding current context to see if we one level of # parentheses inside a macro. if linenum > 0: - for i in xrange(linenum - 1, max(0, linenum - 5), -1): + for i in range(linenum - 1, max(0, linenum - 5), -1): context = clean_lines.elided[i] + context if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): return False @@ -5516,7 +5516,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, required = {} # A map of header name to linenumber and the template entity. # Example of required: { '': (1219, 'less<>') } - for linenum in xrange(clean_lines.NumLines()): + for linenum in range(clean_lines.NumLines()): line = clean_lines.elided[linenum] if not line or line[0] == '#': continue @@ -5570,7 +5570,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, # include_dict is modified during iteration, so we iterate over a copy of # the keys. - header_keys = include_dict.keys() + header_keys = list(include_dict.keys()) for header in header_keys: (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) fullpath = common_path + header @@ -5652,7 +5652,7 @@ def CheckRedundantVirtual(filename, clean_lines, linenum, error): end_col = -1 end_line = -1 start_col = len(virtual.group(2)) - for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): + for start_line in range(linenum, min(linenum + 3, clean_lines.NumLines())): line = clean_lines.elided[start_line][start_col:] parameter_list = Match(r'^([^(]*)\(', line) if parameter_list: @@ -5667,7 +5667,7 @@ def CheckRedundantVirtual(filename, clean_lines, linenum, error): # Look for "override" or "final" after the parameter list # (possibly on the next few lines). - for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())): + for i in range(end_line, min(end_line + 3, clean_lines.NumLines())): line = clean_lines.elided[i][end_col:] match = Search(r'\b(override|final)\b', line) if match: @@ -5924,7 +5924,7 @@ def ProcessFileData(filename, file_extension, lines, error, if IsHeaderExtension(file_extension): CheckForHeaderGuard(filename, clean_lines, error) - for line in xrange(clean_lines.NumLines()): + for line in range(clean_lines.NumLines()): ProcessLine(filename, file_extension, clean_lines, line, include_state, function_state, nesting_state, error, extra_check_functions) diff --git a/media/libaom/src/tools/gen_constrained_tokenset.py b/media/libaom/src/tools/gen_constrained_tokenset.py index 5d12ee1ef5..5fc42656f9 100755 --- a/media/libaom/src/tools/gen_constrained_tokenset.py +++ b/media/libaom/src/tools/gen_constrained_tokenset.py @@ -20,6 +20,7 @@ is first solved, and then the {alpha, beta} pair is used to generate the probabilities for the rest of the nodes. """ +from __future__ import print_function import heapq import sys import numpy as np @@ -108,7 +109,7 @@ def main(bits=15, first_token=1): for q in range(1, 256): parray = get_quantized_spareto(q / 256., beta, bits, first_token) assert parray.sum() == 2**bits - print '{', ', '.join('%d' % i for i in parray), '},' + print('{', ', '.join('%d' % i for i in parray), '},') if __name__ == '__main__': diff --git a/media/libaom/src/tools/gop_bitrate/analyze_data.py b/media/libaom/src/tools/gop_bitrate/analyze_data.py index 4e006b9220..611cc68cdd 100644 --- a/media/libaom/src/tools/gop_bitrate/analyze_data.py +++ b/media/libaom/src/tools/gop_bitrate/analyze_data.py @@ -1,3 +1,4 @@ +from __future__ import print_function with open('experiment.txt', 'r') as file: lines = file.readlines() curr_filename = '' diff --git a/media/libaom/src/tools/gop_bitrate/python/bitrate_accuracy.py b/media/libaom/src/tools/gop_bitrate/python/bitrate_accuracy.py index 2a5da6a794..f1e8ea9c60 100644 --- a/media/libaom/src/tools/gop_bitrate/python/bitrate_accuracy.py +++ b/media/libaom/src/tools/gop_bitrate/python/bitrate_accuracy.py @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np # Model A only. @@ -15,7 +16,7 @@ def pinv_solution(A, mv, B): new_A = np.concatenate((A, mv), axis=1) new_A_inv = np.linalg.pinv(new_A) new_x = np.matmul(new_A_inv, B) - print("pinv solution:", new_x[0][0], new_x[1][0]) + print(("pinv solution:", new_x[0][0], new_x[1][0])) return (new_x[0][0], new_x[1][0]) # Model A only. @@ -160,7 +161,7 @@ def print_solutions(file_path): all_zeros = not A.any() if all_zeros: continue - print("update type:", update[0][0]) + print(("update type:", update[0][0])) x_ls = lstsq_solution(A, B) x_a = minimize_percentage_error_model_a(A, B) x_b = minimize_percentage_error_model_b(A, mv, B) @@ -175,10 +176,10 @@ def print_solutions(file_path): baseline_squared_error_b = average_squared_error_model_b(A, mv, B, [1, 1])[0] print("model,\tframe_coeff,\tmv_coeff,\terror,\tbaseline_error") - print("Model A %_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(percent_error_a) + ",\t" + str(baseline_percent_error_a)) - print("Model A sq_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(squared_error_a) + ",\t" + str(baseline_squared_error_a)) - print("Model B %_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(percent_error_b) + ",\t" + str(baseline_percent_error_b)) - print("Model B sq_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(squared_error_b) + ",\t" + str(baseline_squared_error_b)) + print(("Model A %_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(percent_error_a) + ",\t" + str(baseline_percent_error_a))) + print(("Model A sq_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(squared_error_a) + ",\t" + str(baseline_squared_error_a))) + print(("Model B %_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(percent_error_b) + ",\t" + str(baseline_percent_error_b))) + print(("Model B sq_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(squared_error_b) + ",\t" + str(baseline_squared_error_b))) print() if __name__ == "__main__": diff --git a/media/libaom/src/tools/intersect-diffs.py b/media/libaom/src/tools/intersect-diffs.py index df13c4ef70..87c4a6813e 100755 --- a/media/libaom/src/tools/intersect-diffs.py +++ b/media/libaom/src/tools/intersect-diffs.py @@ -16,6 +16,7 @@ in A and prints them to stdout. This is useful to determine the hunks in B that are relevant to A. The resulting file can be applied with patch(1) on top of A. """ +from __future__ import print_function __author__ = "jkoleszar@google.com" import sys @@ -71,7 +72,7 @@ def main(): break if out_hunks: - print FormatDiffHunks(out_hunks) + print(FormatDiffHunks(out_hunks)) sys.exit(1) if __name__ == "__main__": diff --git a/media/libaom/src/tools/lint-hunks.py b/media/libaom/src/tools/lint-hunks.py index d02bee16ce..18a7063b8c 100755 --- a/media/libaom/src/tools/lint-hunks.py +++ b/media/libaom/src/tools/lint-hunks.py @@ -10,6 +10,7 @@ ## PATENTS file, you can obtain it at www.aomedia.org/license/patent. ## """Performs style checking on each diff hunk.""" +from __future__ import print_function import getopt import os import StringIO @@ -65,17 +66,17 @@ def main(argv=None): try: try: opts, args = getopt.getopt(argv[1:], SHORT_OPTIONS, LONG_OPTIONS) - except getopt.error, msg: + except getopt.error as msg: raise Usage(msg) # process options for o, _ in opts: if o in ("-h", "--help"): - print __doc__ + print(__doc__) sys.exit(0) if args and len(args) > 1: - print __doc__ + print(__doc__) sys.exit(0) # Find the fully qualified path to the root of the tree @@ -105,7 +106,7 @@ def main(argv=None): # Run each affected file through cpplint lint_failed = False - for filename, affected_lines in file_affected_line_map.iteritems(): + for filename, affected_lines in file_affected_line_map.items(): if filename.split(".")[-1] not in ("c", "h", "cc"): continue @@ -129,17 +130,17 @@ def main(argv=None): continue warning_line_num = int(fields[1]) if warning_line_num in affected_lines: - print "%s:%d:%s"%(filename, warning_line_num, - ":".join(fields[2:])) + print("%s:%d:%s"%(filename, warning_line_num, + ":".join(fields[2:]))) lint_failed = True # Set exit code if any relevant lint errors seen if lint_failed: return 1 - except Usage, err: - print >>sys.stderr, err - print >>sys.stderr, "for help use --help" + except Usage as err: + print(err, file=sys.stderr) + print("for help use --help", file=sys.stderr) return 2 if __name__ == "__main__": diff --git a/media/libjxl/src/doc/sphinx/conf.py b/media/libjxl/src/doc/sphinx/conf.py index 1591aefc70..91ca1a621a 100644 --- a/media/libjxl/src/doc/sphinx/conf.py +++ b/media/libjxl/src/doc/sphinx/conf.py @@ -14,13 +14,13 @@ import subprocess def GetVersion(): """Function to get the version of the current code.""" with open(os.path.join( - os.path.dirname(__file__), '../../lib/CMakeLists.txt'), 'r') as f: + os.path.dirname(__file__), '../../lib/CMakeLists.txt')) as f: cmakevars = {} for line in f: m = re.match(r'set\(JPEGXL_([A-Z]+)_VERSION ([^\)]+)\)', line) if m: cmakevars[m.group(1)] = m.group(2) - return '%s.%s.%s' % (cmakevars['MAJOR'], cmakevars['MINOR'], cmakevars['PATCH']) + return '{}.{}.{}'.format(cmakevars['MAJOR'], cmakevars['MINOR'], cmakevars['PATCH']) def ConfigProject(app, config): # Configure the doxygen xml directory as the "xml" directory next to the diff --git a/media/libjxl/src/tools/benchmark/metrics/plots.py b/media/libjxl/src/tools/benchmark/metrics/plots.py index 04b2bb24e5..323202f4ca 100755 --- a/media/libjxl/src/tools/benchmark/metrics/plots.py +++ b/media/libjxl/src/tools/benchmark/metrics/plots.py @@ -13,14 +13,14 @@ _, results, output_dir, *rest = sys.argv OUTPUT = rest[0] if rest else 'svg' # valid values: html, svg, png, webp, jpeg, pdf -with open(results, 'r') as f: +with open(results) as f: reader = csv.DictReader(f) all_results = list(reader) -nonmetric_columns = set([ +nonmetric_columns = { "method", "image", "error", "size", "pixels", "enc_speed", "dec_speed", "bpp", "bppp", "qabpp" -]) +} metrics = set(all_results[0].keys()) - nonmetric_columns @@ -28,10 +28,10 @@ metrics = set(all_results[0].keys()) - nonmetric_columns def codec(method): sm = method.split(':') ssm = set(sm) - speeds = set([ + speeds = { 'kitten', 'falcon', 'wombat', 'cheetah', 'tortoise', 'squirrel', 'hare', 'fast' - ]) + } s = speeds.intersection(ssm) if sm[0] == 'custom': return sm[1] @@ -205,10 +205,10 @@ def style(codec): return configs.get(codec, dict()) -visible_by_default = set([ +visible_by_default = { 'jxl-kitten', 'ssim.444.aom.avif', 'heif', 'webp', 'jpeg', 'xt.jpg', 'default.kdu.j2k' -]) +} column_remap = { 'p': '6-Butteraugli', @@ -234,9 +234,9 @@ def remap(metric): for (m, img) in data: - fname = "%s/%s_%s" % (output_dir, m, img) + fname = "{}/{}_{}".format(output_dir, m, img) fig = go.Figure() - for method in sorted(data[(m, img)].keys(), key=pos): + for method in sorted(list(data[(m, img)].keys()), key=pos): vals = data[(m, img)][method] zvals = list(zip(*sorted(vals))) if not zvals: diff --git a/media/libjxl/src/tools/conformance/conformance.py b/media/libjxl/src/tools/conformance/conformance.py index 6f5ccb659f..7c31706e07 100755 --- a/media/libjxl/src/tools/conformance/conformance.py +++ b/media/libjxl/src/tools/conformance/conformance.py @@ -69,8 +69,8 @@ def CompareBinaries(ref_bin, dec_bin): return True -TEST_KEYS = set( - ['reconstructed_jpeg', 'original_icc', 'rms_error', 'peak_error']) +TEST_KEYS = { + 'reconstructed_jpeg', 'original_icc', 'rms_error', 'peak_error'} def CheckMeta(dec, ref): @@ -113,13 +113,13 @@ def ConformanceTestRunner(args): corpus_dir = os.path.dirname(args.corpus) corpus_txt = args.corpus - with open(corpus_txt, 'r') as f: + with open(corpus_txt) as f: for test_id in f: test_id = test_id.rstrip('\n') print(f"\033[94m\033[1mTesting {test_id}\033[0m", flush=True) test_dir = os.path.join(corpus_dir, test_id) - with open(os.path.join(test_dir, 'test.json'), 'r') as f: + with open(os.path.join(test_dir, 'test.json')) as f: descriptor = json.load(f) if 'sha256sums' in descriptor: del descriptor['sha256sums'] @@ -176,7 +176,7 @@ def ConformanceTestRunner(args): ok = ok & binary_ok # Validate metadata. - with open(meta_filename, 'r') as f: + with open(meta_filename) as f: meta = json.load(f) ok = ok & CheckMeta(meta, descriptor) diff --git a/media/libjxl/src/tools/conformance/generator.py b/media/libjxl/src/tools/conformance/generator.py index e2a9b2e66a..36e5ba5237 100755 --- a/media/libjxl/src/tools/conformance/generator.py +++ b/media/libjxl/src/tools/conformance/generator.py @@ -49,7 +49,7 @@ def GenerateConformanceCorpus(args): test_dir = os.path.join(args.output, test_id) os.makedirs(test_dir, 0o755, exist_ok=True) - print('Generating %s' % (test_id, )) + print('Generating {}'.format(test_id)) input_file = os.path.join(test_dir, 'input.jxl') shutil.copy(jxl, input_file) @@ -69,7 +69,7 @@ def GenerateConformanceCorpus(args): # Decode and generate the reference files. subprocess.check_call(cmd) - with open(metadata_filename, 'r') as f: + with open(metadata_filename) as f: metadata = json.load(f) if os.path.exists(original_icc_filename): diff --git a/media/libjxl/src/tools/optimizer/apply_simplex.py b/media/libjxl/src/tools/optimizer/apply_simplex.py index 2f56766eba..6a6b50212d 100644 --- a/media/libjxl/src/tools/optimizer/apply_simplex.py +++ b/media/libjxl/src/tools/optimizer/apply_simplex.py @@ -34,7 +34,7 @@ import sys def ParseSimplex(fn): """Returns the simplex definition written by simplex_fork.py""" - with open(fn, "r") as f: + with open(fn) as f: line = f.readline() vec = eval(line) return vec @@ -46,17 +46,17 @@ def PythonExpr(c_expr): def repl(m): return m.group(1) - return re.sub("(\d+)f", repl, c_expr) + return re.sub(r"(\d+)f", repl, c_expr) def UpdateSourceFile(fn, vec, keep_bias, id_min, id_max, minval): """Updates expressions containing a bias(N) term.""" - with open(fn, "r") as f: + with open(fn) as f: lines_in = f.readlines() lines_out = [] - rbias = "(bias\((\d+)\))" - r = " -?\d+\.\d+f?( (\+|-|\*) (\d+\.\d+f? \* )?" + rbias + ")" + rbias = r"(bias\((\d+)\))" + r = r" -?\d+\.\d+f?( (\+|-|\*) (\d+\.\d+f? \* )?" + rbias + ")" for line in lines_in: line_out = line x = re.search(r, line) diff --git a/media/libjxl/src/tools/optimizer/simplex_fork.py b/media/libjxl/src/tools/optimizer/simplex_fork.py index a63589d0ae..6978915357 100755 --- a/media/libjxl/src/tools/optimizer/simplex_fork.py +++ b/media/libjxl/src/tools/optimizer/simplex_fork.py @@ -16,10 +16,6 @@ https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method start as ./simplex_fork.py binary dimensions amount """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from six.moves import range import copy import os import random diff --git a/media/libjxl/src/tools/optimizer/update_jpegli_global_scale.py b/media/libjxl/src/tools/optimizer/update_jpegli_global_scale.py index 1a57c59db6..b1e9b20517 100644 --- a/media/libjxl/src/tools/optimizer/update_jpegli_global_scale.py +++ b/media/libjxl/src/tools/optimizer/update_jpegli_global_scale.py @@ -70,11 +70,11 @@ def EvalPnorm(build_dir, corpus_dir, codec): for line in out.splitlines(): if line.startswith(codec): return float(line.split()[8]) - raise Exception("Unexpected benchmark output:\n%sstderr:\n%s" % (out, err)) + raise Exception("Unexpected benchmark output:\n{}stderr:\n{}".format(out, err)) if len(sys.argv) != 3: - print("usage: ", sys.argv[0], "build-dir corpus-dir") + print(("usage: ", sys.argv[0], "build-dir corpus-dir")) exit(1) build_dir = sys.argv[1] diff --git a/media/libjxl/src/tools/scripts/build_cleaner.py b/media/libjxl/src/tools/scripts/build_cleaner.py index 7a357103d8..b55c318546 100644 --- a/media/libjxl/src/tools/scripts/build_cleaner.py +++ b/media/libjxl/src/tools/scripts/build_cleaner.py @@ -170,7 +170,7 @@ def MaybeUpdateFile(args, filename, new_text): otherwise it will return True when no changes were needed. """ filepath = os.path.join(args.src_dir, filename) - with open(filepath, 'r') as f: + with open(filepath) as f: src_text = f.read() if new_text == src_text: @@ -212,7 +212,7 @@ def FormatCMakeVar(name, var): def GetJpegLibVersion(src_dir): - with open(os.path.join(src_dir, 'CMakeLists.txt'), 'r') as f: + with open(os.path.join(src_dir, 'CMakeLists.txt')) as f: cmake_text = f.read() m = re.search(r'set\(JPEGLI_LIBJPEG_LIBRARY_SOVERSION "([0-9]+)"', cmake_text) @@ -229,7 +229,7 @@ def ToDocstringComment(lines): def BuildCleaner(args): repo_files = RepoFiles(args.src_dir) - with open(os.path.join(args.src_dir, 'lib/CMakeLists.txt'), 'r') as f: + with open(os.path.join(args.src_dir, 'lib/CMakeLists.txt')) as f: cmake_text = f.read() version = {'major_version': '', 'minor_version': '', 'patch_version': ''} for var in version.keys(): diff --git a/media/libjxl/src/tools/scripts/check_author.py b/media/libjxl/src/tools/scripts/check_author.py index 7e16859335..074f00820f 100644 --- a/media/libjxl/src/tools/scripts/check_author.py +++ b/media/libjxl/src/tools/scripts/check_author.py @@ -20,7 +20,7 @@ def IsAuthorInFile(email, name, filename): # patterns. email_pattern_regex = re.compile(r'.*<([^>]+)>') - with open(filename, 'r') as f: + with open(filename) as f: for line in f: line = line.strip() if line.startswith('#') or not line: @@ -31,7 +31,7 @@ def IsAuthorInFile(email, name, filename): # Exact email address match is OK, even if the name is different. if fnmatch.fnmatch(line, '* <%s>' % email): print( - "User %s <%s> matched with different name %s" % (name, email, line), + "User {} <{}> matched with different name {}".format(name, email, line), file=sys.stderr) return True # Organizations often have *@domain.com email patterns which don't match @@ -39,14 +39,14 @@ def IsAuthorInFile(email, name, filename): if '*' in line: m = email_pattern_regex.match(line) if m and fnmatch.fnmatch(email, m.group(1)): - print("User %s <%s> matched pattern %s" % (name, email, line), + print("User {} <{}> matched pattern {}".format(name, email, line), file=sys.stderr) return True return False def IndividualsInAlphabeticOrder(filename): """Checks if the names are in alphabetic order""" - with open(filename, 'r') as f: + with open(filename) as f: lines = f.readlines() individual_header = '# Individuals:\n' if individual_header in lines: @@ -70,7 +70,7 @@ def CheckAuthor(args): author_in_file = IsAuthorInFile( args.email, args.name, authors_path) if not author_in_file: - print("User %s <%s> not found, please add yourself to the AUTHORS file" % ( + print("User {} <{}> not found, please add yourself to the AUTHORS file".format( args.name, args.email), file=sys.stderr) print("Hint: to override author in PR run:\n" diff --git a/media/libjxl/src/tools/scripts/demo_progressive_saliency_encoding.py b/media/libjxl/src/tools/scripts/demo_progressive_saliency_encoding.py index 6eb5cadd54..b28ee23a1b 100644 --- a/media/libjxl/src/tools/scripts/demo_progressive_saliency_encoding.py +++ b/media/libjxl/src/tools/scripts/demo_progressive_saliency_encoding.py @@ -26,10 +26,6 @@ Method: """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from six.moves import zip import ast # For ast.literal_eval() only. import os import re diff --git a/media/libjxl/src/tools/upscaling_coefficients/generate_upscaling_coefficients.py b/media/libjxl/src/tools/upscaling_coefficients/generate_upscaling_coefficients.py index 17c404d1cd..31cdb83ca5 100755 --- a/media/libjxl/src/tools/upscaling_coefficients/generate_upscaling_coefficients.py +++ b/media/libjxl/src/tools/upscaling_coefficients/generate_upscaling_coefficients.py @@ -190,11 +190,11 @@ def weights_arrays(upscaling_factor, kernel_size=5): return ( f"kernel[{upscaling_factor}][{upscaling_factor}][{kernel_size}][{kernel_size}]" f" = {{" + ", \n".join("{\n" + ", \n\n".join( - ("{" + ", \n".join("{" + ", ".join( + "{" + ", \n".join("{" + ", ".join( f"weights[{str(indices[kernel_size*i + j][kernel_size*a + b])}]" for b in range(kernel_size)) + "}" for j in range(kernel_size)) + "}" - for a in range(upscaling_factor // 2))) + "\n}" + for a in range(upscaling_factor // 2)) + "\n}" for i in range(upscaling_factor // 2)) + "}\n") diff --git a/media/libopus/gen-sources.py b/media/libopus/gen-sources.py index fdd0f556d2..7bbe9d56a6 100644 --- a/media/libopus/gen-sources.py +++ b/media/libopus/gen-sources.py @@ -34,7 +34,7 @@ def generate_sources_mozbuild(path): values = [] definition_started = False - with open('%s/%s' % (path, makefile), 'r') as mk: + with open('{}/{}'.format(path, makefile)) as mk: for line in mk: line = line.rstrip() result = var_definition.match(line) diff --git a/media/libstagefright/files.py b/media/libstagefright/files.py index 4d6775fa4b..16abe5c951 100644 --- a/media/libstagefright/files.py +++ b/media/libstagefright/files.py @@ -9,7 +9,7 @@ CXXFLAGS=[] CONFIG['_MSC_VER'] = 0 CONFIG['OS_TARGET'] = 0 -class Exports(object): +class Exports: def __init__(self): self.mp4_demuxer=[] @@ -20,10 +20,10 @@ UNIFIED_SOURCES=[] LOCAL_INCLUDES=[] try: - execfile('moz.build') + exec(compile(open('moz.build', "rb").read(), 'moz.build', 'exec')) except: sys.exit(1) for f in SOURCES+UNIFIED_SOURCES: if not f.startswith('binding/'): - print f + print(f) diff --git a/media/libvpx/libvpx/test/android/get_files.py b/media/libvpx/libvpx/test/android/get_files.py index 98ce7b1947..539605ca25 100644 --- a/media/libvpx/libvpx/test/android/get_files.py +++ b/media/libvpx/libvpx/test/android/get_files.py @@ -11,6 +11,7 @@ # 1) File / test_data folder does not exist # 2) SHA mismatch +from __future__ import print_function import pycurl import csv import hashlib diff --git a/media/libvpx/libvpx/test/android/scrape_gtest_log.py b/media/libvpx/libvpx/test/android/scrape_gtest_log.py index 487845c270..2eafa156d6 100644 --- a/media/libvpx/libvpx/test/android/scrape_gtest_log.py +++ b/media/libvpx/libvpx/test/android/scrape_gtest_log.py @@ -13,6 +13,7 @@ waterfall to gather json results mixed in with gtest logs. This is dubious software engineering. """ +from __future__ import print_function import getopt import json import os @@ -22,7 +23,7 @@ import sys def main(): if len(sys.argv) != 3: - print "Expects a file to write json to!" + print("Expects a file to write json to!") exit(1) try: @@ -30,7 +31,7 @@ def main(): getopt.getopt(sys.argv[1:], \ 'o:', ['output-json=']) except getopt.GetOptError: - print 'scrape_gtest_log.py -o ' + print('scrape_gtest_log.py -o ') sys.exit(2) output_json = '' @@ -41,10 +42,10 @@ def main(): blob = sys.stdin.read() json_string = '[' + ','.join('{' + x + '}' for x in re.findall(r'{([^}]*.?)}', blob)) + ']' - print blob + print(blob) output = json.dumps(json.loads(json_string), indent=4, sort_keys=True) - print output + print(output) path = os.path.dirname(output_json) if path and not os.path.exists(path): diff --git a/media/libvpx/libvpx/tools/cpplint.py b/media/libvpx/libvpx/tools/cpplint.py index e3ebde2f5a..e3a97de303 100755 --- a/media/libvpx/libvpx/tools/cpplint.py +++ b/media/libvpx/libvpx/tools/cpplint.py @@ -512,7 +512,7 @@ _ALT_TOKEN_REPLACEMENT = { # False positives include C-style multi-line comments and multi-line strings # but those have always been troublesome for cpplint. _ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( - r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') + r'[ =()](' + ('|'.join(list(_ALT_TOKEN_REPLACEMENT.keys()))) + r')(?=[ (]|$)') # These constants define types of headers for use with diff --git a/media/libvpx/libvpx/tools/intersect-diffs.py b/media/libvpx/libvpx/tools/intersect-diffs.py index 590e687b47..4317fa3f96 100755 --- a/media/libvpx/libvpx/tools/intersect-diffs.py +++ b/media/libvpx/libvpx/tools/intersect-diffs.py @@ -14,6 +14,7 @@ in A and prints them to stdout. This is useful to determine the hunks in B that are relevant to A. The resulting file can be applied with patch(1) on top of A. """ +from __future__ import print_function __author__ = "jkoleszar@google.com" import sys diff --git a/media/libvpx/libvpx/tools/lint-hunks.py b/media/libvpx/libvpx/tools/lint-hunks.py index 0a94afebb9..33f35d568f 100755 --- a/media/libvpx/libvpx/tools/lint-hunks.py +++ b/media/libvpx/libvpx/tools/lint-hunks.py @@ -8,6 +8,7 @@ ## be found in the AUTHORS file in the root of the source tree. ## """Performs style checking on each diff hunk.""" +from __future__ import print_function import getopt import os import io diff --git a/media/libvpx/update.py b/media/libvpx/update.py index 18d7166382..21b8c23a94 100755 --- a/media/libvpx/update.py +++ b/media/libvpx/update.py @@ -2,6 +2,7 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import argparse import os import re @@ -9,15 +10,15 @@ import shutil import sys import subprocess import tarfile -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error from pprint import pprint from StringIO import StringIO def prepare_upstream(prefix, commit=None): upstream_url = 'https://chromium.googlesource.com/webm/libvpx' shutil.rmtree(os.path.join(base, 'libvpx/')) - print(upstream_url + '/+archive/' + commit + '.tar.gz') - urllib.urlretrieve(upstream_url + '/+archive/' + commit + '.tar.gz', 'libvpx.tar.gz') + print((upstream_url + '/+archive/' + commit + '.tar.gz')) + six.moves.urllib.request.urlretrieve(upstream_url + '/+archive/' + commit + '.tar.gz', 'libvpx.tar.gz') tarfile.open('libvpx.tar.gz').extractall(path='libvpx') os.remove(os.path.join(base, 'libvpx.tar.gz')) os.chdir(base) diff --git a/media/libyuv/tools_libyuv/autoroller/roll_deps.py b/media/libyuv/tools_libyuv/autoroller/roll_deps.py index 5496e42403..2113e3cbe5 100755 --- a/media/libyuv/tools_libyuv/autoroller/roll_deps.py +++ b/media/libyuv/tools_libyuv/autoroller/roll_deps.py @@ -175,7 +175,7 @@ def ReadUrlContent(url): conn = urllib.request.urlopen(url) try: return conn.readlines() - except IOError as e: + except OSError as e: logging.exception('Error connecting to %s. Error: %s', url, e) raise finally: @@ -277,7 +277,7 @@ def CalculateChangedClang(new_cr_rev): return match.group(1) raise RollError('Could not parse Clang revision from:\n' + '\n'.join(' ' + l for l in lines)) - with open(CLANG_UPDATE_SCRIPT_LOCAL_PATH, 'r') as f: + with open(CLANG_UPDATE_SCRIPT_LOCAL_PATH) as f: current_lines = f.readlines() current_rev = GetClangRev(current_lines) @@ -291,10 +291,10 @@ def GenerateCommitMessage(current_cr_rev, new_cr_rev, current_commit_pos, new_commit_pos, changed_deps_list, clang_change): current_cr_rev = current_cr_rev[0:10] new_cr_rev = new_cr_rev[0:10] - rev_interval = '%s..%s' % (current_cr_rev, new_cr_rev) - git_number_interval = '%s:%s' % (current_commit_pos, new_commit_pos) + rev_interval = '{}..{}'.format(current_cr_rev, new_cr_rev) + git_number_interval = '{}:{}'.format(current_commit_pos, new_commit_pos) - commit_msg = ['Roll chromium_revision %s (%s)\n' % (rev_interval, + commit_msg = ['Roll chromium_revision {} ({})\n'.format(rev_interval, git_number_interval)] commit_msg.append('Change log: %s' % (CHROMIUM_LOG_TEMPLATE % rev_interval)) commit_msg.append('Full diff: %s\n' % (CHROMIUM_COMMIT_TEMPLATE % @@ -303,7 +303,7 @@ def GenerateCommitMessage(current_cr_rev, new_cr_rev, current_commit_pos, commit_msg.append('Changed dependencies:') for c in changed_deps_list: - commit_msg.append('* %s: %s/+log/%s..%s' % (c.path, c.url, + commit_msg.append('* {}: {}/+log/{}..{}'.format(c.path, c.url, c.current_rev[0:10], c.new_rev[0:10])) change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, 'DEPS') @@ -350,7 +350,7 @@ def UpdateDepsFile(deps_filename, old_cr_revision, new_cr_revision, 'target_os = ["android", "unix", "mac", "ios", "win"];\n' 'Then run "gclient sync" again.' % local_dep_dir) _RunCommand( - ['gclient', 'setdep', '--revision', '%s@%s' % (dep.path, dep.new_rev)], + ['gclient', 'setdep', '--revision', '{}@{}'.format(dep.path, dep.new_rev)], working_dir=CHECKOUT_SRC_DIR) diff --git a/media/libyuv/tools_libyuv/autoroller/unittests/roll_deps_test.py b/media/libyuv/tools_libyuv/autoroller/unittests/roll_deps_test.py index af86bdd586..9acce41989 100755 --- a/media/libyuv/tools_libyuv/autoroller/unittests/roll_deps_test.py +++ b/media/libyuv/tools_libyuv/autoroller/unittests/roll_deps_test.py @@ -55,11 +55,11 @@ class FakeCmd(): def __call__(self, *args, **kwargs): if not self.expectations: - raise TestError('Got unexpected\n%s\n%s' % (args, kwargs)) + raise TestError('Got unexpected\n{}\n{}'.format(args, kwargs)) exp_args, exp_kwargs, exp_returns = self.expectations.pop(0) if args != exp_args or kwargs != exp_kwargs: - message = 'Expected:\n args: %s\n kwargs: %s\n' % (exp_args, exp_kwargs) - message += 'Got:\n args: %s\n kwargs: %s\n' % (args, kwargs) + message = 'Expected:\n args: {}\n kwargs: {}\n'.format(exp_args, exp_kwargs) + message += 'Got:\n args: {}\n kwargs: {}\n'.format(args, kwargs) raise TestError(message) return exp_returns @@ -92,13 +92,13 @@ class TestRollChromiumRevision(unittest.TestCase): current_rev = TEST_DATA_VARS['chromium_revision'] UpdateDepsFile(self._libyuv_depsfile, current_rev, new_rev, []) - with open(self._libyuv_depsfile, 'r') as deps_file: + with open(self._libyuv_depsfile) as deps_file: deps_contents = deps_file.read() self.assertTrue(new_rev in deps_contents, - 'Failed to find %s in\n%s' % (new_rev, deps_contents)) + 'Failed to find {} in\n{}'.format(new_rev, deps_contents)) def testParseDepsDict(self): - with open(self._libyuv_depsfile, 'r') as deps_file: + with open(self._libyuv_depsfile) as deps_file: deps_contents = deps_file.read() local_scope = ParseDepsDict(deps_contents) vars_dict = local_scope['vars'] diff --git a/media/mtransport/third_party/import.py b/media/mtransport/third_party/import.py index 6defdf26b7..6a99a579e3 100644 --- a/media/mtransport/third_party/import.py +++ b/media/mtransport/third_party/import.py @@ -6,6 +6,7 @@ # Execute as: /import.py # must have 'IMPORT_FILES' in it +from __future__ import print_function import sys import re import os @@ -30,7 +31,7 @@ for l in f: FILES.append(l) for f in FILES: - print f + print(f) SOURCE_PATH = "%s/%s"%(DISTRO,f) DEST_PATH = "%s/%s"%(IMPORT_DIR,f) if not os.path.exists(SOURCE_PATH): diff --git a/media/webrtc/trunk/build/android/adb_logcat_monitor.py b/media/webrtc/trunk/build/android/adb_logcat_monitor.py index aeaef0b093..4f3cd258c5 100755 --- a/media/webrtc/trunk/build/android/adb_logcat_monitor.py +++ b/media/webrtc/trunk/build/android/adb_logcat_monitor.py @@ -16,6 +16,7 @@ resilient across phone disconnects and reconnects and start the logcat early enough to not miss anything. """ +from __future__ import print_function import logging import os import re @@ -98,7 +99,7 @@ def main(base_dir, adb_cmd='adb'): """Monitor adb forever. Expects a SIGINT (Ctrl-C) to kill.""" # We create the directory to ensure 'run once' semantics if os.path.exists(base_dir): - print 'adb_logcat_monitor: %s already exists? Cleaning' % base_dir + print('adb_logcat_monitor: %s already exists? Cleaning' % base_dir) shutil.rmtree(base_dir, ignore_errors=True) os.makedirs(base_dir) @@ -138,7 +139,7 @@ def main(base_dir, adb_cmd='adb'): except: logging.exception('Unexpected exception in main.') finally: - for process, _ in devices.itervalues(): + for process, _ in devices.values(): if process: try: process.terminate() @@ -149,7 +150,7 @@ def main(base_dir, adb_cmd='adb'): if __name__ == '__main__': if 2 <= len(sys.argv) <= 3: - print 'adb_logcat_monitor: Initializing' + print('adb_logcat_monitor: Initializing') sys.exit(main(*sys.argv[1:3])) - print 'Usage: %s []' % sys.argv[0] + print('Usage: %s []' % sys.argv[0]) diff --git a/media/webrtc/trunk/build/android/adb_logcat_printer.py b/media/webrtc/trunk/build/android/adb_logcat_printer.py index 5194668ec6..ea24b2aff8 100755 --- a/media/webrtc/trunk/build/android/adb_logcat_printer.py +++ b/media/webrtc/trunk/build/android/adb_logcat_printer.py @@ -18,6 +18,7 @@ will attempt to terminate the contained PID by sending a SIGINT and monitoring for the deletion of the aforementioned file. """ +from __future__ import print_function import cStringIO import logging import os @@ -106,7 +107,7 @@ def GetDeviceLogs(log_filenames, logger): """ device_logs = [] - for device, device_files in log_filenames.iteritems(): + for device, device_files in log_filenames.items(): logger.debug('%s: %s', device, str(device_files)) device_file_lines = [] for cur_file in device_files: @@ -197,6 +198,6 @@ def main(base_dir, output_file): if __name__ == '__main__': if len(sys.argv) == 1: - print 'Usage: %s ' % sys.argv[0] + print('Usage: %s ' % sys.argv[0]) sys.exit(1) sys.exit(main(sys.argv[1], sys.stdout)) diff --git a/media/webrtc/trunk/build/android/device_stats_monitor.py b/media/webrtc/trunk/build/android/device_stats_monitor.py index 181c3db5ff..cf3d41c9f9 100755 --- a/media/webrtc/trunk/build/android/device_stats_monitor.py +++ b/media/webrtc/trunk/build/android/device_stats_monitor.py @@ -10,6 +10,7 @@ Usage: ./device_stats_monitor.py --hz=20 --duration=5 --outfile=/tmp/foo """ +from __future__ import print_function import optparse import os import sys @@ -34,10 +35,10 @@ def main(argv): monitor = device_stats_monitor.DeviceStatsMonitor( android_commands.AndroidCommands(), options.hz, options.build_type) monitor.Start() - print 'Waiting for %d seconds while profiling.' % options.duration + print('Waiting for %d seconds while profiling.' % options.duration) time.sleep(options.duration) url = monitor.StopAndCollect(options.outfile) - print 'View results in browser at %s' % url + print('View results in browser at %s' % url) if __name__ == '__main__': sys.exit(main(sys.argv)) diff --git a/media/webrtc/trunk/build/android/device_status_check.py b/media/webrtc/trunk/build/android/device_status_check.py index 3d695a2235..db8541f6b6 100755 --- a/media/webrtc/trunk/build/android/device_status_check.py +++ b/media/webrtc/trunk/build/android/device_status_check.py @@ -5,6 +5,7 @@ # found in the LICENSE file. """A class to keep track of devices across builds and report state.""" +from __future__ import print_function import logging import optparse import os @@ -112,7 +113,7 @@ def CheckForMissingDevices(options, adb_online_devs): 'adb devices: %s' % GetCmdOutput(['adb', 'devices']), 'adb devices(GetAttachedDevices): %s' % GetAttachedDevices()]) - print body + print(body) # Only send email if the first time a particular device goes offline last_missing = ReadDeviceList('.last_missing') @@ -129,15 +130,15 @@ def CheckForMissingDevices(options, adb_online_devs): server.sendmail(from_address, [to_address], msg_body) server.quit() except Exception as e: - print 'Failed to send alert email. Error: %s' % e + print('Failed to send alert email. Error: %s' % e) else: new_devs = set(adb_online_devs) - set(last_devices) if new_devs and os.path.exists(last_devices_path): buildbot_report.PrintWarning() buildbot_report.PrintSummaryText( '%d new devices detected' % len(new_devs)) - print ('New devices detected %s. And now back to your ' - 'regularly scheduled program.' % list(new_devs)) + print(('New devices detected %s. And now back to your ' + 'regularly scheduled program.' % list(new_devs))) WriteDeviceList('.last_devices', (adb_online_devs + last_devices)) WriteDeviceList('.last_missing', missing_devs) @@ -156,14 +157,14 @@ def main(): devices = GetAttachedDevices() types, builds, reports = [], [], [] if devices: - types, builds, reports = zip(*[DeviceInfo(dev) for dev in devices]) + types, builds, reports = list(zip(*[DeviceInfo(dev) for dev in devices])) unique_types = list(set(types)) unique_builds = list(set(builds)) buildbot_report.PrintMsg('Online devices: %d. Device types %s, builds %s' % (len(devices), unique_types, unique_builds)) - print '\n'.join(reports) + print('\n'.join(reports)) CheckForMissingDevices(options, devices) if __name__ == '__main__': diff --git a/media/webrtc/trunk/build/android/emulator.py b/media/webrtc/trunk/build/android/emulator.py index 77c9a75daa..d27c424495 100755 --- a/media/webrtc/trunk/build/android/emulator.py +++ b/media/webrtc/trunk/build/android/emulator.py @@ -82,7 +82,7 @@ class PortPool(object): a killed emulator "hangs on" to a port long enough to prevent relaunch. This is especially true on slow machines (like a bot). Cycling through a port start position helps make us resilient.""" - ports = range(cls._port_min, cls._port_max, 2) + ports = list(range(cls._port_min, cls._port_max, 2)) n = cls._port_current_index cls._port_current_index = (n + 1) % len(ports) return ports[n:] + ports[:n] diff --git a/media/webrtc/trunk/build/android/lighttpd_server.py b/media/webrtc/trunk/build/android/lighttpd_server.py index 11ae794d4a..a0936507db 100755 --- a/media/webrtc/trunk/build/android/lighttpd_server.py +++ b/media/webrtc/trunk/build/android/lighttpd_server.py @@ -10,9 +10,10 @@ Usage: lighttpd_server PATH_TO_DOC_ROOT """ +from __future__ import print_function import codecs import contextlib -import httplib +import six.moves.http_client import os import random import shutil @@ -103,8 +104,8 @@ class LighttpdServer(object): self.process.close() if self.fixed_port or not 'in use' in server_error: - print 'Client error:', client_error - print 'Server error:', server_error + print('Client error:', client_error) + print('Server error:', server_error) return False self.port = self._GetRandomPort() return True @@ -118,10 +119,10 @@ class LighttpdServer(object): def _TestServerConnection(self): # Wait for server to start server_msg = '' - for timeout in xrange(1, 5): + for timeout in range(1, 5): client_error = None try: - with contextlib.closing(httplib.HTTPConnection( + with contextlib.closing(six.moves.http_client.HTTPConnection( '127.0.0.1', self.port, timeout=timeout)) as http: http.set_debuglevel(timeout > 3) http.request('HEAD', '/') @@ -133,7 +134,7 @@ class LighttpdServer(object): client_error = ('Bad response: %s %s version %s\n ' % (r.status, r.reason, r.version) + '\n '.join([': '.join(h) for h in r.getheaders()])) - except (httplib.HTTPException, socket.error) as client_error: + except (six.moves.http_client.HTTPException, socket.error) as client_error: pass # Probably too quick connecting: try again # Check for server startup error messages ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'], @@ -241,10 +242,10 @@ def main(argv): server = LighttpdServer(*argv[1:]) try: if server.StartupHttpServer(): - raw_input('Server running at http://127.0.0.1:%s -' + input('Server running at http://127.0.0.1:%s -' ' press Enter to exit it.' % server.port) else: - print 'Server exit code:', server.process.exitstatus + print('Server exit code:', server.process.exitstatus) finally: server.ShutdownHttpServer() diff --git a/media/webrtc/trunk/build/android/pylib/android_commands.py b/media/webrtc/trunk/build/android/pylib/android_commands.py index 8a1562caad..f5d100050a 100644 --- a/media/webrtc/trunk/build/android/pylib/android_commands.py +++ b/media/webrtc/trunk/build/android/pylib/android_commands.py @@ -7,6 +7,7 @@ Assumes adb binary is currently on system path. """ +from __future__ import print_function import collections import datetime import logging @@ -18,7 +19,7 @@ import sys import tempfile import time -import io_stats_parser +from . import io_stats_parser from pylib import pexpect CHROME_SRC = os.path.join( @@ -27,7 +28,7 @@ CHROME_SRC = os.path.join( sys.path.append(os.path.join(CHROME_SRC, 'third_party', 'android_testrunner')) import adb_interface -import cmd_helper +from . import cmd_helper import errors # is under ../../../third_party/android_testrunner/errors.py @@ -347,7 +348,7 @@ class AndroidCommands(object): if 'Success' in install_status: return install_status except errors.WaitForResponseTimedOutError: - print '@@@STEP_WARNINGS@@@' + print('@@@STEP_WARNINGS@@@') logging.info('Timeout on installing %s' % apk_path) if reboots_left <= 0: @@ -587,7 +588,7 @@ class AndroidCommands(object): if not os.path.exists(md5sum_path): md5sum_path = '%s/out/Release/md5sum_bin' % (CHROME_SRC) if not os.path.exists(md5sum_path): - print >> sys.stderr, 'Please build md5sum.' + print('Please build md5sum.', file=sys.stderr) sys.exit(1) command = 'push %s %s' % (md5sum_path, MD5SUM_DEVICE_PATH) assert _HasAdbPushSucceeded(self._adb.SendCommand(command)) @@ -671,7 +672,7 @@ class AndroidCommands(object): temp_props_file = tempfile.NamedTemporaryFile() properties = '' if self._adb.Pull(LOCAL_PROPERTIES_PATH, temp_props_file.name): - properties = file(temp_props_file.name).read() + properties = open(temp_props_file.name).read() re_search = re.compile(r'^\s*' + re.escape(JAVA_ASSERT_PROPERTY) + r'\s*=\s*all\s*$', re.MULTILINE) if enable != bool(re.search(re_search, properties)): @@ -681,7 +682,7 @@ class AndroidCommands(object): if enable: properties += '\n%s=all\n' % JAVA_ASSERT_PROPERTY - file(temp_props_file.name, 'w').write(properties) + open(temp_props_file.name, 'w').write(properties) self._adb.Push(temp_props_file.name, LOCAL_PROPERTIES_PATH) # Next, check the current runtime value is what we need, and diff --git a/media/webrtc/trunk/build/android/pylib/apk_info.py b/media/webrtc/trunk/build/android/pylib/apk_info.py index 7e8867570b..bfdbc5e73f 100644 --- a/media/webrtc/trunk/build/android/pylib/apk_info.py +++ b/media/webrtc/trunk/build/android/pylib/apk_info.py @@ -8,7 +8,7 @@ import collections import os import re -import cmd_helper +from . import cmd_helper class ApkInfo(object): @@ -129,7 +129,7 @@ class ApkInfo(object): def GetAnnotatedTests(self, annotation_filter_list): """Returns a list of all tests that match the given annotation filters.""" - return [test for test, annotations in self._GetAnnotationMap().iteritems() + return [test for test, annotations in self._GetAnnotationMap(.items()) if self._IsTestMethod(test) and self._AnnotationsMatchFilters( annotation_filter_list, annotations)] diff --git a/media/webrtc/trunk/build/android/pylib/base_test_runner.py b/media/webrtc/trunk/build/android/pylib/base_test_runner.py index 619bc6edf0..10ed5f0904 100644 --- a/media/webrtc/trunk/build/android/pylib/base_test_runner.py +++ b/media/webrtc/trunk/build/android/pylib/base_test_runner.py @@ -3,21 +3,21 @@ # found in the LICENSE file. import contextlib -import httplib +import six.moves.http_client import logging import os import tempfile import time -import android_commands -import constants -from chrome_test_server_spawner import SpawningServer -import constants -from flag_changer import FlagChanger -from forwarder import Forwarder +from . import android_commands +from . import constants +from .chrome_test_server_spawner import SpawningServer +from . import constants +from .flag_changer import FlagChanger +from .forwarder import Forwarder import lighttpd_server -import ports -from valgrind_tools import CreateTool +from . import ports +from .valgrind_tools import CreateTool # A file on device to store ports of net test server. The format of the file is @@ -181,7 +181,7 @@ class BaseTestRunner(object): server_ready = False error_msgs = [] # Try 3 times to launch test spawner server. - for i in xrange(0, 3): + for i in range(0, 3): # Do not allocate port for test server here. We will allocate # different port for individual test in TestServerThread. self.test_server_spawner_port = ports.AllocateTestServerPort() diff --git a/media/webrtc/trunk/build/android/pylib/base_test_sharder.py b/media/webrtc/trunk/build/android/pylib/base_test_sharder.py index 48206c202c..a818c1f753 100644 --- a/media/webrtc/trunk/build/android/pylib/base_test_sharder.py +++ b/media/webrtc/trunk/build/android/pylib/base_test_sharder.py @@ -6,7 +6,7 @@ import logging import multiprocessing -from test_result import TestResults +from .test_result import TestResults def _ShardedTestRunnable(test): @@ -78,7 +78,7 @@ class BaseTestSharder(object): logging.warning('Look for the "Final result" banner in the end.') logging.warning('*' * 80) final_results = TestResults() - for retry in xrange(self.retries): + for retry in range(self.retries): logging.warning('Try %d of %d', retry + 1, self.retries) self.SetupSharding(self.tests) test_runners = [] diff --git a/media/webrtc/trunk/build/android/pylib/buildbot_report.py b/media/webrtc/trunk/build/android/pylib/buildbot_report.py index fe3fcd638e..dc68171b29 100644 --- a/media/webrtc/trunk/build/android/pylib/buildbot_report.py +++ b/media/webrtc/trunk/build/android/pylib/buildbot_report.py @@ -4,6 +4,7 @@ """Helper functions to print buildbot messages.""" +from __future__ import print_function def PrintLink(label, url): """Adds a link with name |label| linking to |url| to current buildbot step. @@ -11,7 +12,7 @@ def PrintLink(label, url): label: A string with the name of the label. url: A string of the URL. """ - print '@@@STEP_LINK@%s@%s@@@' % (label, url) + print('@@@STEP_LINK@%s@%s@@@' % (label, url)) def PrintMsg(msg): @@ -20,7 +21,7 @@ def PrintMsg(msg): Args: msg: String to be appended. """ - print '@@@STEP_TEXT@%s@@@' % msg + print('@@@STEP_TEXT@%s@@@' % msg) def PrintSummaryText(msg): @@ -29,18 +30,18 @@ def PrintSummaryText(msg): Args: msg: String to be appended. """ - print '@@@STEP_SUMMARY_TEXT@%s@@@' % msg + print('@@@STEP_SUMMARY_TEXT@%s@@@' % msg) def PrintError(): """Marks the current step as failed.""" - print '@@@STEP_FAILURE@@@' + print('@@@STEP_FAILURE@@@') def PrintWarning(): """Marks the current step with a warning.""" - print '@@@STEP_WARNINGS@@@' + print('@@@STEP_WARNINGS@@@') def PrintNamedStep(step): - print '@@@BUILD_STEP %s@@@' % step + print('@@@BUILD_STEP %s@@@' % step) diff --git a/media/webrtc/trunk/build/android/pylib/chrome_test_server_spawner.py b/media/webrtc/trunk/build/android/pylib/chrome_test_server_spawner.py index 512a6091db..e46acf4d88 100644 --- a/media/webrtc/trunk/build/android/pylib/chrome_test_server_spawner.py +++ b/media/webrtc/trunk/build/android/pylib/chrome_test_server_spawner.py @@ -8,7 +8,7 @@ It's used to accept requests from the device to spawn and kill instances of the chrome test server on the host. """ -import BaseHTTPServer +import six.moves.BaseHTTPServer import json import logging import os @@ -17,11 +17,11 @@ import struct import subprocess import threading import time -import urlparse +import six.moves.urllib.parse -import constants -from forwarder import Forwarder -import ports +from . import constants +from .forwarder import Forwarder +from . import ports # Path that are needed to import necessary modules when running testserver.py. @@ -147,7 +147,7 @@ class TestServerThread(threading.Thread): return False logging.info('Got port json data: %s', port_json) port_json = json.loads(port_json) - if port_json.has_key('port') and isinstance(port_json['port'], int): + if 'port' in port_json and isinstance(port_json['port'], int): self.host_port = port_json['port'] return _CheckPortStatus(self.host_port, True) logging.error('Failed to get port information from the server data.') @@ -177,29 +177,29 @@ class TestServerThread(threading.Thread): data_dir = os.path.join(constants.CHROME_DIR, data_dir) self.command_line.append('--data-dir=%s' % data_dir) # The following arguments are optional depending on the individual test. - if self.arguments.has_key('log-to-console'): + if 'log-to-console' in self.arguments: self.command_line.append('--log-to-console') - if self.arguments.has_key('auth-token'): + if 'auth-token' in self.arguments: self.command_line.append('--auth-token=%s' % self.arguments['auth-token']) - if self.arguments.has_key('https'): + if 'https' in self.arguments: self.command_line.append('--https') - if self.arguments.has_key('cert-and-key-file'): + if 'cert-and-key-file' in self.arguments: self.command_line.append('--cert-and-key-file=%s' % os.path.join( constants.CHROME_DIR, self.arguments['cert-and-key-file'])) - if self.arguments.has_key('ocsp'): + if 'ocsp' in self.arguments: self.command_line.append('--ocsp=%s' % self.arguments['ocsp']) - if self.arguments.has_key('https-record-resume'): + if 'https-record-resume' in self.arguments: self.command_line.append('--https-record-resume') - if self.arguments.has_key('ssl-client-auth'): + if 'ssl-client-auth' in self.arguments: self.command_line.append('--ssl-client-auth') - if self.arguments.has_key('tls-intolerant'): + if 'tls-intolerant' in self.arguments: self.command_line.append('--tls-intolerant=%s' % self.arguments['tls-intolerant']) - if self.arguments.has_key('ssl-client-ca'): + if 'ssl-client-ca' in self.arguments: for ca in self.arguments['ssl-client-ca']: self.command_line.append('--ssl-client-ca=%s' % os.path.join(constants.CHROME_DIR, ca)) - if self.arguments.has_key('ssl-bulk-cipher'): + if 'ssl-bulk-cipher' in self.arguments: for bulk_cipher in self.arguments['ssl-bulk-cipher']: self.command_line.append('--ssl-bulk-cipher=%s' % bulk_cipher) @@ -261,7 +261,7 @@ class TestServerThread(threading.Thread): self.wait_event.wait() -class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): +class SpawningServerRequestHandler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler): """A handler used to process http GET/POST request.""" def _SendResponse(self, response_code, response_reason, additional_headers, @@ -344,7 +344,7 @@ class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.server.test_server_instance = None def do_POST(self): - parsed_path = urlparse.urlparse(self.path) + parsed_path = six.moves.urllib.parse.urlparse(self.path) action = parsed_path.path logging.info('Action for POST method is: %s.', action) if action == '/start': @@ -354,9 +354,9 @@ class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): logging.info('Encounter unknown request: %s.', action) def do_GET(self): - parsed_path = urlparse.urlparse(self.path) + parsed_path = six.moves.urllib.parse.urlparse(self.path) action = parsed_path.path - params = urlparse.parse_qs(parsed_path.query, keep_blank_values=1) + params = six.moves.urllib.parse.parse_qs(parsed_path.query, keep_blank_values=1) logging.info('Action for GET method is: %s.', action) for param in params: logging.info('%s=%s', param, params[param][0]) @@ -378,7 +378,7 @@ class SpawningServer(object): def __init__(self, test_server_spawner_port, adb, tool, build_type): logging.info('Creating new spawner on port: %d.', test_server_spawner_port) - self.server = BaseHTTPServer.HTTPServer(('', test_server_spawner_port), + self.server = six.moves.BaseHTTPServer.HTTPServer(('', test_server_spawner_port), SpawningServerRequestHandler) self.port = test_server_spawner_port self.server.adb = adb diff --git a/media/webrtc/trunk/build/android/pylib/debug_info.py b/media/webrtc/trunk/build/android/pylib/debug_info.py index 6f0f55a33f..856087f7dd 100644 --- a/media/webrtc/trunk/build/android/pylib/debug_info.py +++ b/media/webrtc/trunk/build/android/pylib/debug_info.py @@ -13,7 +13,7 @@ import string import subprocess import tempfile -import cmd_helper +from . import cmd_helper TOMBSTONE_DIR = '/data/tombstones/' diff --git a/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py b/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py index 8be4efae59..bb6700f8a6 100644 --- a/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py +++ b/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py @@ -9,10 +9,10 @@ import json import os import subprocess import sys -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error -import constants -import io_stats_parser +from . import constants +from . import io_stats_parser class DeviceStatsMonitor(object): @@ -95,7 +95,7 @@ class DeviceStatsMonitor(object): with open(output_path, 'w') as f: f.write('display(%d, %s, %s);' % (self._hz, json.dumps(results), units)) return 'file://%s?results=file://%s' % ( - DeviceStatsMonitor.RESULT_VIEWER_PATH, urllib.quote(output_path)) + DeviceStatsMonitor.RESULT_VIEWER_PATH, six.moves.urllib.parse.quote(output_path)) @staticmethod diff --git a/media/webrtc/trunk/build/android/pylib/fake_dns.py b/media/webrtc/trunk/build/android/pylib/fake_dns.py index 1c64490045..df9afb8e99 100644 --- a/media/webrtc/trunk/build/android/pylib/fake_dns.py +++ b/media/webrtc/trunk/build/android/pylib/fake_dns.py @@ -2,8 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import android_commands -import constants +from . import android_commands +from . import constants import logging import os import subprocess diff --git a/media/webrtc/trunk/build/android/pylib/flag_changer.py b/media/webrtc/trunk/build/android/pylib/flag_changer.py index 6210561568..1fd425fedf 100644 --- a/media/webrtc/trunk/build/android/pylib/flag_changer.py +++ b/media/webrtc/trunk/build/android/pylib/flag_changer.py @@ -2,7 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import constants +from __future__ import print_function +from . import constants import traceback import warnings @@ -86,7 +87,7 @@ class FlagChanger(object): def _UpdateCommandLineFile(self): """Writes out the command line to the file, or removes it if empty.""" - print "Current flags: ", self._current_flags + print("Current flags: ", self._current_flags) if self._current_flags: self._android_cmd.SetFileContents(CHROME_COMMAND_FILE, diff --git a/media/webrtc/trunk/build/android/pylib/forwarder.py b/media/webrtc/trunk/build/android/pylib/forwarder.py index bc41db3ff3..d271fb464d 100644 --- a/media/webrtc/trunk/build/android/pylib/forwarder.py +++ b/media/webrtc/trunk/build/android/pylib/forwarder.py @@ -8,10 +8,10 @@ import re import sys import time -import android_commands -import cmd_helper -import constants -import ports +from . import android_commands +from . import cmd_helper +from . import constants +from . import ports from pylib import pexpect diff --git a/media/webrtc/trunk/build/android/pylib/java_unittest_utils.py b/media/webrtc/trunk/build/android/pylib/java_unittest_utils.py index b5446dcf95..e11aa879fe 100644 --- a/media/webrtc/trunk/build/android/pylib/java_unittest_utils.py +++ b/media/webrtc/trunk/build/android/pylib/java_unittest_utils.py @@ -6,8 +6,8 @@ import os -import android_commands -from run_java_tests import TestRunner +from . import android_commands +from .run_java_tests import TestRunner def _GetPackageName(fname): diff --git a/media/webrtc/trunk/build/android/pylib/json_perf_parser.py b/media/webrtc/trunk/build/android/pylib/json_perf_parser.py index 1a8e617539..7e105877f0 100644 --- a/media/webrtc/trunk/build/android/pylib/json_perf_parser.py +++ b/media/webrtc/trunk/build/android/pylib/json_perf_parser.py @@ -65,7 +65,7 @@ def GetAverageRunInfo(json_data, name): def EntryFilter(entry): return entry['cat'] == 'Java' and entry['name'] == name - filtered_entries = filter(EntryFilter, json_data) + filtered_entries = list(filter(EntryFilter, json_data)) result = {} diff --git a/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py b/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py index c0a3ee413d..e642ba16ff 100644 --- a/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py +++ b/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py @@ -2,9 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function import re -import android_commands +from . import android_commands import math # Valid values of result type. @@ -75,7 +76,7 @@ def PrintPerfResult(measurement, trace, values, units, result_type='default', if sd: output += '\nSd %s: %f%s' % (measurement, sd, units) if print_to_stdout: - print output + print(output) return output diff --git a/media/webrtc/trunk/build/android/pylib/ports.py b/media/webrtc/trunk/build/android/pylib/ports.py index e9b6b901e0..1284c924ba 100644 --- a/media/webrtc/trunk/build/android/pylib/ports.py +++ b/media/webrtc/trunk/build/android/pylib/ports.py @@ -6,15 +6,15 @@ import contextlib import fcntl -import httplib +import six.moves.http_client import logging import os import re import socket import traceback -import cmd_helper -import constants +from . import cmd_helper +from . import constants #The following two methods are used to allocate the port source for various @@ -143,10 +143,10 @@ def IsHttpServerConnectable(host, port, tries=3, command='GET', path='/', message the server returns when connect status is false. """ assert tries >= 1 - for i in xrange(0, tries): + for i in range(0, tries): client_error = None try: - with contextlib.closing(httplib.HTTPConnection( + with contextlib.closing(six.moves.http_client.HTTPConnection( host, port, timeout=timeout)) as http: # Output some debug information when we have tried more than 2 times. http.set_debuglevel(i >= 2) @@ -158,7 +158,7 @@ def IsHttpServerConnectable(host, port, tries=3, command='GET', path='/', client_error = ('Bad response: %s %s version %s\n ' % (r.status, r.reason, r.version) + '\n '.join([': '.join(h) for h in r.getheaders()])) - except (httplib.HTTPException, socket.error) as e: + except (six.moves.http_client.HTTPException, socket.error) as e: # Probably too quick connecting: try again. exception_error_msgs = traceback.format_exception_only(type(e), e) if exception_error_msgs: diff --git a/media/webrtc/trunk/build/android/pylib/python_test_base.py b/media/webrtc/trunk/build/android/pylib/python_test_base.py index 3517cdda83..3546fe98d4 100644 --- a/media/webrtc/trunk/build/android/pylib/python_test_base.py +++ b/media/webrtc/trunk/build/android/pylib/python_test_base.py @@ -23,10 +23,10 @@ import logging import os import time -import android_commands -import apk_info -from run_java_tests import TestRunner -from test_result import SingleTestResult, TestResults +from . import android_commands +from . import apk_info +from .run_java_tests import TestRunner +from .test_result import SingleTestResult, TestResults # aka the parent of com.google.android diff --git a/media/webrtc/trunk/build/android/pylib/python_test_caller.py b/media/webrtc/trunk/build/android/pylib/python_test_caller.py index 882b892997..d1da3a2f2a 100644 --- a/media/webrtc/trunk/build/android/pylib/python_test_caller.py +++ b/media/webrtc/trunk/build/android/pylib/python_test_caller.py @@ -9,7 +9,7 @@ import logging import sys import time -from test_result import TestResults +from .test_result import TestResults def CallPythonTest(test, options): diff --git a/media/webrtc/trunk/build/android/pylib/python_test_sharder.py b/media/webrtc/trunk/build/android/pylib/python_test_sharder.py index e27096d788..eca12de54d 100644 --- a/media/webrtc/trunk/build/android/pylib/python_test_sharder.py +++ b/media/webrtc/trunk/build/android/pylib/python_test_sharder.py @@ -8,10 +8,10 @@ import copy import logging import multiprocessing -from python_test_caller import CallPythonTest -from run_java_tests import FatalTestException -import sharded_tests_queue -from test_result import TestResults +from .python_test_caller import CallPythonTest +from .run_java_tests import FatalTestException +from . import sharded_tests_queue +from .test_result import TestResults def SetTestsContainer(tests_container): @@ -123,7 +123,7 @@ class PythonTestSharder(object): all_passed = [] test_results = TestResults() tests_to_run = self.tests - for retry in xrange(self.retries): + for retry in range(self.retries): logging.warning('Try %d of %d', retry + 1, self.retries) self._SetupSharding(self.tests) test_runners = self._MakeTestRunners(self.attached_devices) @@ -197,7 +197,7 @@ class PythonTestSharder(object): A list of test objects which correspond to test names found in failed_tests, or an empty list if there is no correspondence. """ - failed_test_names = map(lambda t: t.test_name, failed_tests) + failed_test_names = [t.test_name for t in failed_tests] tests_to_retry = [t for t in available_tests if t.qualified_name in failed_test_names] return tests_to_retry diff --git a/media/webrtc/trunk/build/android/pylib/run_java_tests.py b/media/webrtc/trunk/build/android/pylib/run_java_tests.py index fc0a13fd81..77e01858bd 100644 --- a/media/webrtc/trunk/build/android/pylib/run_java_tests.py +++ b/media/webrtc/trunk/build/android/pylib/run_java_tests.py @@ -12,19 +12,19 @@ import shutil import sys import time -import android_commands -import apk_info -from base_test_runner import BaseTestRunner -from base_test_sharder import BaseTestSharder, SetTestsContainer -import cmd_helper -import constants +from . import android_commands +from . import apk_info +from .base_test_runner import BaseTestRunner +from .base_test_sharder import BaseTestSharder, SetTestsContainer +from . import cmd_helper +from . import constants import errors -from forwarder import Forwarder -from json_perf_parser import GetAverageRunInfoFromJSONString -from perf_tests_helper import PrintPerfResult -import sharded_tests_queue -from test_result import SingleTestResult, TestResults -import valgrind_tools +from .forwarder import Forwarder +from .json_perf_parser import GetAverageRunInfoFromJSONString +from .perf_tests_helper import PrintPerfResult +from . import sharded_tests_queue +from .test_result import SingleTestResult, TestResults +from . import valgrind_tools _PERF_TEST_ANNOTATION = 'PerfTest' @@ -477,7 +477,7 @@ class TestRunner(BaseTestRunner): # See ../../third_party/android/testrunner/adb_interface.py except (errors.WaitForResponseTimedOutError, errors.DeviceUnresponsiveError, - errors.InstrumentationError), e: + errors.InstrumentationError) as e: if start_date_ms: duration_ms = int(time.time()) * 1000 - start_date_ms else: diff --git a/media/webrtc/trunk/build/android/pylib/run_python_tests.py b/media/webrtc/trunk/build/android/pylib/run_python_tests.py index 7d39f48295..f628c02ea3 100644 --- a/media/webrtc/trunk/build/android/pylib/run_python_tests.py +++ b/media/webrtc/trunk/build/android/pylib/run_python_tests.py @@ -9,16 +9,16 @@ import os import sys import types -import android_commands -import apk_info -import constants -import python_test_base -from python_test_caller import CallPythonTest -from python_test_sharder import PythonTestSharder -import run_java_tests -from run_java_tests import FatalTestException -from test_info_collection import TestInfoCollection -from test_result import TestResults +from . import android_commands +from . import apk_info +from . import constants +from . import python_test_base +from .python_test_caller import CallPythonTest +from .python_test_sharder import PythonTestSharder +from . import run_java_tests +from .run_java_tests import FatalTestException +from .test_info_collection import TestInfoCollection +from .test_result import TestResults def _GetPythonFiles(root, files): @@ -155,7 +155,7 @@ def _GetTestsFromClass(test_class): """ test_names = [m for m in dir(test_class) if _IsTestMethod(m, test_class)] - return map(test_class, test_names) + return list(map(test_class, test_names)) def _GetTestClassesFromModule(test_module): @@ -168,7 +168,7 @@ def _GetTestClassesFromModule(test_module): def _IsTestClass(test_class): - return (type(test_class) is types.TypeType and + return (type(test_class) is type and issubclass(test_class, python_test_base.PythonTestBase) and test_class is not python_test_base.PythonTestBase) diff --git a/media/webrtc/trunk/build/android/pylib/run_tests_helper.py b/media/webrtc/trunk/build/android/pylib/run_tests_helper.py index 15e5d5381b..edb37ea656 100644 --- a/media/webrtc/trunk/build/android/pylib/run_tests_helper.py +++ b/media/webrtc/trunk/build/android/pylib/run_tests_helper.py @@ -12,7 +12,7 @@ def GetExpectations(file_name): """Returns a list of test names in the |file_name| test expectations file.""" if not file_name or not os.path.exists(file_name): return [] - return [x for x in [x.strip() for x in file(file_name).readlines()] + return [x for x in [x.strip() for x in open(file_name).readlines()] if x and x[0] != '#'] diff --git a/media/webrtc/trunk/build/android/pylib/sharded_tests_queue.py b/media/webrtc/trunk/build/android/pylib/sharded_tests_queue.py index 9e28e2c484..8aff1698bc 100644 --- a/media/webrtc/trunk/build/android/pylib/sharded_tests_queue.py +++ b/media/webrtc/trunk/build/android/pylib/sharded_tests_queue.py @@ -27,7 +27,7 @@ class ShardedTestsQueue(object): self.tests_queue = multiprocessing.Queue() for test in tests: self.tests_queue.put(test) - for _ in xrange(self.num_devices): + for _ in range(self.num_devices): self.tests_queue.put(ShardedTestsQueue._STOP_SENTINEL) def __iter__(self): diff --git a/media/webrtc/trunk/build/android/pylib/single_test_runner.py b/media/webrtc/trunk/build/android/pylib/single_test_runner.py index a680c68f16..fda7d3328d 100644 --- a/media/webrtc/trunk/build/android/pylib/single_test_runner.py +++ b/media/webrtc/trunk/build/android/pylib/single_test_runner.py @@ -7,14 +7,14 @@ import logging import os import sys -from base_test_runner import BaseTestRunner -import debug_info -import constants -import perf_tests_helper -import run_tests_helper -from test_package_apk import TestPackageApk -from test_package_executable import TestPackageExecutable -from test_result import TestResults +from .base_test_runner import BaseTestRunner +from . import debug_info +from . import constants +from . import perf_tests_helper +from . import run_tests_helper +from .test_package_apk import TestPackageApk +from .test_package_executable import TestPackageExecutable +from .test_result import TestResults class SingleTestRunner(BaseTestRunner): @@ -127,7 +127,7 @@ class SingleTestRunner(BaseTestRunner): os.unlink(filter_file_name) return - filter_file = file(filter_file_name, 'w') + filter_file = open(filter_file_name, 'w') if self._running_on_emulator: filter_file.write('# Addtional list of suppressions from emulator\n') else: diff --git a/media/webrtc/trunk/build/android/pylib/test_info_collection.py b/media/webrtc/trunk/build/android/pylib/test_info_collection.py index fc4e806941..315b4755fc 100644 --- a/media/webrtc/trunk/build/android/pylib/test_info_collection.py +++ b/media/webrtc/trunk/build/android/pylib/test_info_collection.py @@ -7,7 +7,7 @@ import logging import os -import tests_annotations +from . import tests_annotations class TestInfo(object): diff --git a/media/webrtc/trunk/build/android/pylib/test_options_parser.py b/media/webrtc/trunk/build/android/pylib/test_options_parser.py index ee00f1fffd..e6dc3885c9 100644 --- a/media/webrtc/trunk/build/android/pylib/test_options_parser.py +++ b/media/webrtc/trunk/build/android/pylib/test_options_parser.py @@ -4,7 +4,7 @@ """Parses options for the instrumentation tests.""" -import constants +from . import constants import optparse import os import sys diff --git a/media/webrtc/trunk/build/android/pylib/test_package.py b/media/webrtc/trunk/build/android/pylib/test_package.py index a47ed72d89..b4ac58a4af 100644 --- a/media/webrtc/trunk/build/android/pylib/test_package.py +++ b/media/webrtc/trunk/build/android/pylib/test_package.py @@ -7,10 +7,10 @@ import logging import re import os -import constants -from perf_tests_helper import PrintPerfResult +from . import constants +from .perf_tests_helper import PrintPerfResult from pylib import pexpect -from test_result import BaseTestResult, TestResults +from .test_result import BaseTestResult, TestResults # TODO(bulach): TestPackage, TestPackageExecutable and diff --git a/media/webrtc/trunk/build/android/pylib/test_package_apk.py b/media/webrtc/trunk/build/android/pylib/test_package_apk.py index 42b9ade68b..9211a2225c 100644 --- a/media/webrtc/trunk/build/android/pylib/test_package_apk.py +++ b/media/webrtc/trunk/build/android/pylib/test_package_apk.py @@ -3,15 +3,16 @@ # found in the LICENSE file. +from __future__ import print_function import os import shlex import sys import tempfile import time -import android_commands -import constants -from test_package import TestPackage +from . import android_commands +from . import constants +from .test_package import TestPackage from pylib import pexpect class TestPackageApk(TestPackage): @@ -61,7 +62,7 @@ class TestPackageApk(TestPackage): def _WatchFifo(self, timeout, logfile=None): for i in range(10): if self.adb.FileExistsOnDevice(self._GetFifo()): - print 'Fifo created...' + print('Fifo created...') break time.sleep(i) else: diff --git a/media/webrtc/trunk/build/android/pylib/test_package_executable.py b/media/webrtc/trunk/build/android/pylib/test_package_executable.py index a11c768fbb..36ea575f2b 100644 --- a/media/webrtc/trunk/build/android/pylib/test_package_executable.py +++ b/media/webrtc/trunk/build/android/pylib/test_package_executable.py @@ -9,9 +9,9 @@ import shutil import sys import tempfile -import cmd_helper -import constants -from test_package import TestPackage +from . import cmd_helper +from . import constants +from .test_package import TestPackage from pylib import pexpect @@ -54,7 +54,7 @@ class TestPackageExecutable(TestPackage): logging.critical('Unable to pull gtest ret val file %s', ret_code_file.name) raise ValueError - ret_code = file(ret_code_file.name).read() + ret_code = open(ret_code_file.name).read() ret = int(ret_code) except ValueError: logging.critical('Error reading gtest ret val file %s [%s]', diff --git a/media/webrtc/trunk/build/android/pylib/test_result.py b/media/webrtc/trunk/build/android/pylib/test_result.py index 31a546acac..0aa683f309 100644 --- a/media/webrtc/trunk/build/android/pylib/test_result.py +++ b/media/webrtc/trunk/build/android/pylib/test_result.py @@ -3,14 +3,15 @@ # found in the LICENSE file. +from __future__ import print_function import json import logging import os import time import traceback -import buildbot_report -import constants +from . import buildbot_report +from . import constants class BaseTestResult(object): @@ -146,9 +147,9 @@ class TestResults(object): full_file_name = os.path.join(log_file_path, test_group) if not os.path.exists(full_file_name): with open(full_file_name, 'w') as log_file: - print >> log_file, '\n%s results for %s build %s:' % ( + print('\n%s results for %s build %s:' % ( test_group, os.environ.get('BUILDBOT_BUILDERNAME'), - os.environ.get('BUILDBOT_BUILDNUMBER')) + os.environ.get('BUILDBOT_BUILDNUMBER')), file=log_file) log_contents = [' %s result : %d tests ran' % (test_suite, len(self.ok) + len(self.failed) + @@ -160,14 +161,14 @@ class TestResults(object): if count: log_contents.append(', %d tests %s' % (count, result)) with open(full_file_name, 'a') as log_file: - print >> log_file, ''.join(log_contents) + print(''.join(log_contents), file=log_file) content = {'test_group': test_group, 'ok': [t.name for t in self.ok], 'failed': [t.name for t in self.failed], 'crashed': [t.name for t in self.failed], 'unknown': [t.name for t in self.unknown],} with open(os.path.join(log_file_path, 'results.json'), 'a') as json_file: - print >> json_file, json.dumps(content) + print(json.dumps(content), file=json_file) # Summarize in the test output. summary_string = 'Summary:\n' @@ -190,4 +191,4 @@ class TestResults(object): elif self.failed or self.crashed or self.overall_fail: buildbot_report.PrintError() else: - print 'Step success!' # No annotation needed + print('Step success!') # No annotation needed diff --git a/media/webrtc/trunk/build/android/pylib/tests_annotations.py b/media/webrtc/trunk/build/android/pylib/tests_annotations.py index f2a183466d..bac2b41179 100644 --- a/media/webrtc/trunk/build/android/pylib/tests_annotations.py +++ b/media/webrtc/trunk/build/android/pylib/tests_annotations.py @@ -23,7 +23,7 @@ class AnnotatedFunctions(object): """ module_name = os.path.splitext(os.path.basename( function.__globals__['__file__']))[0] - qualified_function_name = '.'.join([module_name, function.func_name]) + qualified_function_name = '.'.join([module_name, function.__name__]) function_list = AnnotatedFunctions._ANNOTATED.get(annotation, []) function_list.append(qualified_function_name) AnnotatedFunctions._ANNOTATED[annotation] = function_list @@ -52,7 +52,7 @@ class AnnotatedFunctions(object): List of all annotations for this function. """ return [annotation - for annotation, tests in AnnotatedFunctions._ANNOTATED.iteritems() + for annotation, tests in AnnotatedFunctions._ANNOTATED.items() if qualified_function_name in tests] diff --git a/media/webrtc/trunk/build/android/pylib/valgrind_tools.py b/media/webrtc/trunk/build/android/pylib/valgrind_tools.py index 810f6be188..43a8b25f9d 100644 --- a/media/webrtc/trunk/build/android/pylib/valgrind_tools.py +++ b/media/webrtc/trunk/build/android/pylib/valgrind_tools.py @@ -21,10 +21,11 @@ Run the test as usual. Call tool.CleanUpEnvironment(). """ +from __future__ import print_function import os.path import sys -from constants import CHROME_DIR +from .constants import CHROME_DIR def SetChromeTimeoutScale(adb, scale): @@ -250,6 +251,6 @@ def CreateTool(tool_name, adb): if ctor: return ctor(adb) else: - print 'Unknown tool %s, available tools: %s' % ( - tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) + print('Unknown tool %s, available tools: %s' % ( + tool_name, ', '.join(sorted(TOOL_REGISTRY.keys())))) sys.exit(1) diff --git a/media/webrtc/trunk/build/android/run_tests.py b/media/webrtc/trunk/build/android/run_tests.py index 8a8bd26954..37fae2e227 100755 --- a/media/webrtc/trunk/build/android/run_tests.py +++ b/media/webrtc/trunk/build/android/run_tests.py @@ -49,6 +49,7 @@ loaded. We don't care about the rare testcases which succeeded on emuatlor, but failed on device. """ +from __future__ import print_function import fnmatch import logging import optparse @@ -220,10 +221,8 @@ class TestSharder(BaseTestSharder): if not rebaseline: disabled_list = test.GetDisabledTests() # Only includes tests that do not have any match in the disabled list. - all_tests = filter(lambda t: - not any([fnmatch.fnmatch(t, disabled_pattern) - for disabled_pattern in disabled_list]), - all_tests) + all_tests = [t for t in all_tests if not any([fnmatch.fnmatch(t, disabled_pattern) + for disabled_pattern in disabled_list])] self.tests = all_tests def CreateShardedTestRunner(self, device, index): @@ -292,8 +291,8 @@ def _RunATestSuite(options): buildbot_emulators.append(buildbot_emulator) attached_devices.append(buildbot_emulator.device) # Wait for all emulators to boot completed. - map(lambda buildbot_emulator: buildbot_emulator.ConfirmLaunch(True), - buildbot_emulators) + list(map(lambda buildbot_emulator: buildbot_emulator.ConfirmLaunch(True), + buildbot_emulators)) elif options.test_device: attached_devices = [options.test_device] else: @@ -370,9 +369,9 @@ def Dispatch(options): def ListTestSuites(): """Display a list of available test suites.""" - print 'Available test suites are:' + print('Available test suites are:') for test_suite in _TEST_SUITES: - print test_suite + print(test_suite) def main(argv): @@ -427,7 +426,7 @@ def main(argv): options, args = option_parser.parse_args(argv) if len(args) > 1: - print 'Unknown argument:', args[1:] + print('Unknown argument:', args[1:]) option_parser.print_usage() sys.exit(1) run_tests_helper.SetLogLevel(options.verbose_count) diff --git a/media/webrtc/trunk/build/apply_locales.py b/media/webrtc/trunk/build/apply_locales.py index 6af7280fad..7dd80152be 100755 --- a/media/webrtc/trunk/build/apply_locales.py +++ b/media/webrtc/trunk/build/apply_locales.py @@ -5,6 +5,7 @@ # TODO: remove this script when GYP has for loops +from __future__ import print_function import sys import optparse @@ -20,7 +21,7 @@ def main(argv): (options, arglist) = parser.parse_args(argv) if len(arglist) < 3: - print 'ERROR: need string and list of locales' + print('ERROR: need string and list of locales') return 1 str_template = arglist[1] @@ -39,7 +40,7 @@ def main(argv): # Quote each element so filename spaces don't mess up GYP's attempt to parse # it into a list. - print ' '.join(["'%s'" % x for x in results]) + print(' '.join(["'%s'" % x for x in results])) if __name__ == '__main__': sys.exit(main(sys.argv)) diff --git a/media/webrtc/trunk/build/compiler_version.py b/media/webrtc/trunk/build/compiler_version.py index eae7b176dd..dabfe0f2a5 100755 --- a/media/webrtc/trunk/build/compiler_version.py +++ b/media/webrtc/trunk/build/compiler_version.py @@ -9,6 +9,7 @@ Print gcc version as XY if you are running gcc X.Y.*. This is used to tweak build flags for gcc 4.4. """ +from __future__ import print_function import os import re import subprocess @@ -26,11 +27,11 @@ def GetVersion(compiler): result = re.match(r"(\d+)\.(\d+)", gcc_output) return result.group(1) + result.group(2) - except Exception, e: + except Exception as e: if gcc_error: sys.stderr.write(gcc_error) - print >> sys.stderr, "compiler_version.py failed to execute:", compiler - print >> sys.stderr, e + print("compiler_version.py failed to execute:", compiler, file=sys.stderr) + print(e, file=sys.stderr) return "" def GetVersionFromEnvironment(compiler_env): @@ -56,18 +57,18 @@ def main(): # target compiler's version number as gcc_version in Android. cxx_version = GetVersionFromEnvironment("CXX_target") if cxx_version: - print cxx_version + print(cxx_version) return 0 cxx_version = GetVersionFromEnvironment("CXX") if cxx_version: - print cxx_version + print(cxx_version) return 0 # Otherwise we check the g++ version. gccversion = GetVersion("g++") if gccversion != "": - print gccversion + print(gccversion) return 0 return 1 diff --git a/media/webrtc/trunk/build/copy_test_data_ios.py b/media/webrtc/trunk/build/copy_test_data_ios.py index 5130735835..d4485cefcc 100755 --- a/media/webrtc/trunk/build/copy_test_data_ios.py +++ b/media/webrtc/trunk/build/copy_test_data_ios.py @@ -5,6 +5,7 @@ """Copies test data files or directories into a given output directory.""" +from __future__ import print_function import optparse import os import shutil @@ -93,11 +94,11 @@ def DoMain(argv): def main(argv): try: result = DoMain(argv[1:]) - except WrongNumberOfArgumentsException, e: - print >>sys.stderr, e + except WrongNumberOfArgumentsException as e: + print(e, file=sys.stderr) return 1 if result: - print result + print(result) return 0 if __name__ == '__main__': diff --git a/media/webrtc/trunk/build/download_nacl_toolchains.py b/media/webrtc/trunk/build/download_nacl_toolchains.py index c2007d0f10..c52a2db803 100755 --- a/media/webrtc/trunk/build/download_nacl_toolchains.py +++ b/media/webrtc/trunk/build/download_nacl_toolchains.py @@ -5,6 +5,7 @@ """Shim to run nacl toolchain download script only if there is a nacl dir.""" +from __future__ import print_function import os import sys @@ -19,9 +20,9 @@ def Main(args): nacl_build_dir = os.path.join(nacl_dir, 'build') download_script = os.path.join(nacl_build_dir, 'download_toolchains.py') if not os.path.exists(download_script): - print "Can't find '%s'" % download_script - print 'Presumably you are intentionally building without NativeClient.' - print 'Skipping NativeClient toolchain download.' + print("Can't find '%s'" % download_script) + print('Presumably you are intentionally building without NativeClient.') + print('Skipping NativeClient toolchain download.') sys.exit(0) sys.path.insert(0, nacl_build_dir) import download_toolchains @@ -46,7 +47,7 @@ def Main(args): if buildbot_name.find('pnacl') >= 0 and buildbot_name.find('sdk') >= 0: use_pnacl = True if use_pnacl: - print '\n*** DOWNLOADING PNACL TOOLCHAIN ***\n' + print('\n*** DOWNLOADING PNACL TOOLCHAIN ***\n') else: args.append('--no-pnacl') diff --git a/media/webrtc/trunk/build/escape_unicode.py b/media/webrtc/trunk/build/escape_unicode.py index 859ba5d03d..2fe5947c68 100755 --- a/media/webrtc/trunk/build/escape_unicode.py +++ b/media/webrtc/trunk/build/escape_unicode.py @@ -5,6 +5,7 @@ """Convert any unicode characters found in the input file to C literals.""" +from __future__ import print_function import codecs import optparse import os @@ -20,17 +21,17 @@ def main(argv): options, arglist = parser.parse_args(argv) if not options.output_dir: - print "output_dir required" + print("output_dir required") return 1 if len(arglist) != 2: - print "input_file required" + print("input_file required") return 1 in_filename = arglist[1] if not in_filename.endswith('.utf8'): - print "input_file should end in .utf8" + print("input_file should end in .utf8") return 1 out_filename = os.path.join(options.output_dir, os.path.basename( diff --git a/media/webrtc/trunk/build/extract_from_cab.py b/media/webrtc/trunk/build/extract_from_cab.py index 1c928af36f..fd781c733b 100755 --- a/media/webrtc/trunk/build/extract_from_cab.py +++ b/media/webrtc/trunk/build/extract_from_cab.py @@ -5,6 +5,7 @@ """Extracts a single file from a CAB archive.""" +from __future__ import print_function import os import shutil import subprocess @@ -17,12 +18,12 @@ def run_quiet(*args): out, _ = popen.communicate() if popen.returncode: # expand emits errors to stdout, so if we fail, then print that out. - print out + print(out) return popen.returncode def main(): if len(sys.argv) != 4: - print 'Usage: extract_from_cab.py cab_path archived_file output_dir' + print('Usage: extract_from_cab.py cab_path archived_file output_dir') return 1 [cab_path, archived_file, output_dir] = sys.argv[1:] diff --git a/media/webrtc/trunk/build/linux/rewrite_dirs.py b/media/webrtc/trunk/build/linux/rewrite_dirs.py index 30f22f0cd6..7faf4ca944 100755 --- a/media/webrtc/trunk/build/linux/rewrite_dirs.py +++ b/media/webrtc/trunk/build/linux/rewrite_dirs.py @@ -5,6 +5,7 @@ """Rewrites paths in -I, -L and other option to be relative to a sysroot.""" +from __future__ import print_function import sys import os import optparse @@ -63,7 +64,7 @@ def main(argv): for line in sys.stdin.readlines(): line = RewriteLine(line.strip(), opts) - print line + print(line) return 0 diff --git a/media/webrtc/trunk/build/mac/change_mach_o_flags.py b/media/webrtc/trunk/build/mac/change_mach_o_flags.py index c2aeaec9b1..a0d455d703 100755 --- a/media/webrtc/trunk/build/mac/change_mach_o_flags.py +++ b/media/webrtc/trunk/build/mac/change_mach_o_flags.py @@ -106,8 +106,7 @@ def CheckedSeek(file, offset): file.seek(offset, os.SEEK_SET) new_offset = file.tell() if new_offset != offset: - raise MachOError, \ - 'seek: expected offset %d, observed %d' % (offset, new_offset) + raise MachOError('seek: expected offset %d, observed %d' % (offset, new_offset)) def CheckedRead(file, count): @@ -116,8 +115,7 @@ def CheckedRead(file, count): bytes = file.read(count) if len(bytes) != count: - raise MachOError, \ - 'read: expected length %d, observed %d' % (count, len(bytes)) + raise MachOError('read: expected length %d, observed %d' % (count, len(bytes))) return bytes @@ -189,17 +187,15 @@ def HandleMachOFile(file, options, offset=0): elif magic == MH_CIGAM or magic == MH_CIGAM_64: endian = '>' else: - raise MachOError, \ - 'Mach-O file at offset %d has illusion of magic' % offset + raise MachOError('Mach-O file at offset %d has illusion of magic' % offset) CheckedSeek(file, offset) magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = \ ReadMachHeader(file, endian) assert magic == MH_MAGIC or magic == MH_MAGIC_64 if filetype != MH_EXECUTE: - raise MachOError, \ - 'Mach-O file at offset %d is type 0x%x, expected MH_EXECUTE' % \ - (offset, filetype) + raise MachOError('Mach-O file at offset %d is type 0x%x, expected MH_EXECUTE' % \ + (offset, filetype)) original_flags = flags @@ -228,7 +224,7 @@ def HandleFatFile(file, options, fat_offset=0): nfat_arch = ReadUInt32(file, '>') - for index in xrange(0, nfat_arch): + for index in range(0, nfat_arch): cputype, cpusubtype, offset, size, align = ReadFatArch(file) assert size >= 28 @@ -263,7 +259,7 @@ def main(me, args): magic == MH_MAGIC_64 or magic == MH_CIGAM_64: HandleMachOFile(executable_file, options) else: - raise MachOError, '%s is not a Mach-O or fat file' % executable_file + raise MachOError('%s is not a Mach-O or fat file' % executable_file) executable_file.close() return 0 diff --git a/media/webrtc/trunk/build/mac/find_sdk.py b/media/webrtc/trunk/build/mac/find_sdk.py index 5be134a707..e9a318c236 100755 --- a/media/webrtc/trunk/build/mac/find_sdk.py +++ b/media/webrtc/trunk/build/mac/find_sdk.py @@ -3,6 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function import os import re import subprocess @@ -20,7 +21,7 @@ from optparse import OptionParser def parse_version(version_str): """'10.5' => [10, 5]""" - return map(int, re.findall(r'(\d+)', version_str)) + return list(map(int, re.findall(r'(\d+)', version_str))) def main(): @@ -40,8 +41,8 @@ def main(): stderr=subprocess.STDOUT) out, err = job.communicate() if job.returncode != 0: - print >>sys.stderr, out - print >>sys.stderr, err + print(out, file=sys.stderr) + print(err, file=sys.stderr) raise Exception(('Error %d running xcode-select, you might have to run ' '|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| ' 'if you are using Xcode 4.') % job.returncode) @@ -63,21 +64,19 @@ def main(): best_sdk = "" if options.verify and best_sdk != min_sdk_version and not options.sdk_path: - print >>sys.stderr, '' - print >>sys.stderr, ' vvvvvvv' - print >>sys.stderr, '' - print >>sys.stderr, \ - 'This build requires the %s SDK, but it was not found on your system.' \ - % min_sdk_version - print >>sys.stderr, \ - 'Either install it, or explicitly set mac_sdk in your GYP_DEFINES.' - print >>sys.stderr, '' - print >>sys.stderr, ' ^^^^^^^' - print >>sys.stderr, '' + print('', file=sys.stderr) + print(' vvvvvvv', file=sys.stderr) + print('', file=sys.stderr) + print('This build requires the %s SDK, but it was not found on your system.' \ + % min_sdk_version, file=sys.stderr) + print('Either install it, or explicitly set mac_sdk in your GYP_DEFINES.', file=sys.stderr) + print('', file=sys.stderr) + print(' ^^^^^^^', file=sys.stderr) + print('', file=sys.stderr) return min_sdk_version return best_sdk if __name__ == '__main__': - print main() + print(main()) diff --git a/media/webrtc/trunk/build/mac/tweak_info_plist.py b/media/webrtc/trunk/build/mac/tweak_info_plist.py index 9b57e7da01..751f3214fc 100755 --- a/media/webrtc/trunk/build/mac/tweak_info_plist.py +++ b/media/webrtc/trunk/build/mac/tweak_info_plist.py @@ -20,6 +20,7 @@ # by the time the app target is done, the info.plist is correct. # +from __future__ import print_function import optparse import os from os import environ as env @@ -115,7 +116,7 @@ def _DoSCMKeys(plist, add_keys): if scm_revision != None: plist['SCMRevision'] = scm_revision elif add_keys: - print >>sys.stderr, 'Could not determine SCM revision. This may be OK.' + print('Could not determine SCM revision. This may be OK.', file=sys.stderr) if scm_path != None: plist['SCMPath'] = scm_path @@ -232,7 +233,7 @@ def Main(argv): (options, args) = parser.parse_args(argv) if len(args) > 0: - print >>sys.stderr, parser.get_usage() + print(parser.get_usage(), file=sys.stderr) return 1 # Read the plist into its parsed format. @@ -246,7 +247,7 @@ def Main(argv): # Add Breakpad if configured to do so. if options.use_breakpad: if options.branding is None: - print >>sys.stderr, 'Use of Breakpad requires branding.' + print('Use of Breakpad requires branding.', file=sys.stderr) return 1 _AddBreakpadKeys(plist, options.branding) if options.breakpad_uploads: @@ -265,7 +266,7 @@ def Main(argv): # Only add Keystone in Release builds. if options.use_keystone and env['CONFIGURATION'] == 'Release': if options.bundle_identifier is None: - print >>sys.stderr, 'Use of Keystone requires the bundle id.' + print('Use of Keystone requires the bundle id.', file=sys.stderr) return 1 _AddKeystoneKeys(plist, options.bundle_identifier) else: diff --git a/media/webrtc/trunk/build/util/lastchange.py b/media/webrtc/trunk/build/util/lastchange.py index a101341ef7..5ca702f053 100755 --- a/media/webrtc/trunk/build/util/lastchange.py +++ b/media/webrtc/trunk/build/util/lastchange.py @@ -7,6 +7,7 @@ lastchange.py -- Chromium revision fetching utility. """ +from __future__ import print_function import re import optparse import os @@ -215,7 +216,7 @@ def main(argv=None): version_info.revision = '0' if opts.revision_only: - print version_info.revision + print(version_info.revision) else: contents = "LASTCHANGE=%s\n" % version_info.revision if out_file: diff --git a/media/webrtc/trunk/build/win/install-build-deps.py b/media/webrtc/trunk/build/win/install-build-deps.py index d9e50b6e7e..a976b81db3 100755 --- a/media/webrtc/trunk/build/win/install-build-deps.py +++ b/media/webrtc/trunk/build/win/install-build-deps.py @@ -3,6 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function import shutil import sys import os @@ -18,11 +19,11 @@ def patch_msbuild(): backup_path = source_path + ".backup" if not os.path.exists(backup_path): try: - print "Backing up %s..." % source_path + print("Backing up %s..." % source_path) shutil.copyfile(source_path, backup_path) except IOError: - print "Could not back up %s to %s. Run as Administrator?" % ( - source_path, backup_path) + print("Could not back up %s to %s. Run as Administrator?" % ( + source_path, backup_path)) return 1 source = open(source_path).read() @@ -35,7 +36,7 @@ def patch_msbuild(): if result != source: open(source_path, "w").write(result) - print "Patched %s." % source_path + print("Patched %s." % source_path) return 0 diff --git a/media/webrtc/trunk/google_apis/build/check_internal.py b/media/webrtc/trunk/google_apis/build/check_internal.py index da0ddae805..5a43944921 100755 --- a/media/webrtc/trunk/google_apis/build/check_internal.py +++ b/media/webrtc/trunk/google_apis/build/check_internal.py @@ -9,12 +9,13 @@ Takes one argument, a path. Prints 1 if the path exists, 0 if not. """ +from __future__ import print_function import os import sys if __name__ == '__main__': if os.path.exists(sys.argv[1]): - print 1 + print(1) else: - print 0 + print(0) diff --git a/media/webrtc/trunk/testing/generate_gmock_mutant.py b/media/webrtc/trunk/testing/generate_gmock_mutant.py index 01176da39b..7b1756d333 100755 --- a/media/webrtc/trunk/testing/generate_gmock_mutant.py +++ b/media/webrtc/trunk/testing/generate_gmock_mutant.py @@ -376,7 +376,7 @@ def FixCode(s): def GenerateDispatch(prebound, calltime): - print "\n// %d - %d" % (prebound, calltime) + print("\n// %d - %d" % (prebound, calltime)) args = { "template_params": Merge([Gen("typename P%", prebound), Gen("typename C%", calltime)]), @@ -385,12 +385,12 @@ def GenerateDispatch(prebound, calltime): "args": Merge([GenAlpha("p.%", prebound), GenAlpha("c.%", calltime)]), } - print FixCode(DISPATCH_TO_METHOD_TEMPLATE % args) - print FixCode(DISPATCH_TO_FUNCTION_TEMPLATE % args) + print(FixCode(DISPATCH_TO_METHOD_TEMPLATE % args)) + print(FixCode(DISPATCH_TO_FUNCTION_TEMPLATE % args)) def GenerateCreateFunctor(prebound, calltime): - print "// %d - %d" % (prebound, calltime) + print("// %d - %d" % (prebound, calltime)) args = { "calltime": GenTuple("A%", calltime), "prebound": GenTuple("P%", prebound), @@ -403,51 +403,51 @@ def GenerateCreateFunctor(prebound, calltime): } mutant = FixCode(CREATE_METHOD_FUNCTOR_TEMPLATE % args) - print mutant + print(mutant) # Slightly different version for free function call. - print "\n", FixCode(CREATE_FUNCTION_FUNCTOR_TEMPLATE % args) + print("\n", FixCode(CREATE_FUNCTION_FUNCTOR_TEMPLATE % args)) # Functor with pointer to a pointer of the object. - print "\n#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING" + print("\n#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING") mutant2 = mutant.replace("CreateFunctor(T* obj,", "CreateFunctor(T** obj,") mutant2 = mutant2.replace("new Mutant", "new MutantLateObjectBind") mutant2 = mutant2.replace(" " * 17 + "Tuple", " " * 31 + "Tuple") - print mutant2 - print "#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING\n" + print(mutant2) + print("#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING\n") # OS_WIN specific. Same functors but with stdcall calling conventions. # Functor for method with __stdcall calling conventions. - print "#if defined (OS_WIN)" + print("#if defined (OS_WIN)") stdcall_method = CREATE_METHOD_FUNCTOR_TEMPLATE stdcall_method = stdcall_method.replace("U::", "__stdcall U::") stdcall_method = FixCode(stdcall_method % args) - print stdcall_method + print(stdcall_method) # Functor for free function with __stdcall calling conventions. stdcall_function = CREATE_FUNCTION_FUNCTOR_TEMPLATE stdcall_function = stdcall_function.replace("R (*", "R (__stdcall *"); - print "\n", FixCode(stdcall_function % args) + print("\n", FixCode(stdcall_function % args)) - print "#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING" + print("#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING") stdcall2 = stdcall_method; stdcall2 = stdcall2.replace("CreateFunctor(T* obj,", "CreateFunctor(T** obj,") stdcall2 = stdcall2.replace("new Mutant", "new MutantLateObjectBind") stdcall2 = stdcall2.replace(" " * 17 + "Tuple", " " * 31 + "Tuple") - print stdcall2 - print "#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING" - print "#endif // OS_WIN\n" + print(stdcall2) + print("#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING") + print("#endif // OS_WIN\n") def main(): - print HEADER - for prebound in xrange(0, 6 + 1): - for args in xrange(0, 6 + 1): + print(HEADER) + for prebound in range(0, 6 + 1): + for args in range(0, 6 + 1): GenerateDispatch(prebound, args) - print MUTANT - for prebound in xrange(0, 6 + 1): - for args in xrange(0, 6 + 1): + print(MUTANT) + for prebound in range(0, 6 + 1): + for args in range(0, 6 + 1): GenerateCreateFunctor(prebound, args) - print FOOTER + print(FOOTER) return 0 diff --git a/media/webrtc/trunk/testing/gtest/scripts/fuse_gtest_files.py b/media/webrtc/trunk/testing/gtest/scripts/fuse_gtest_files.py index 57ef72f0e3..f1ff68c4d8 100755 --- a/media/webrtc/trunk/testing/gtest/scripts/fuse_gtest_files.py +++ b/media/webrtc/trunk/testing/gtest/scripts/fuse_gtest_files.py @@ -90,8 +90,8 @@ def VerifyFileExists(directory, relative_path): """ if not os.path.isfile(os.path.join(directory, relative_path)): - print 'ERROR: Cannot find %s in directory %s.' % (relative_path, - directory) + print('ERROR: Cannot find {} in directory {}.'.format(relative_path, + directory)) print ('Please either specify a valid project root directory ' 'or omit it on the command line.') sys.exit(1) @@ -119,11 +119,11 @@ def VerifyOutputFile(output_dir, relative_path): # TODO(wan@google.com): The following user-interaction doesn't # work with automated processes. We should provide a way for the # Makefile to force overwriting the files. - print ('%s already exists in directory %s - overwrite it? (y/N) ' % + print('%s already exists in directory %s - overwrite it? (y/N) ' % (relative_path, output_dir)) answer = sys.stdin.readline().strip() if answer not in ['y', 'Y']: - print 'ABORTED.' + print('ABORTED.') sys.exit(1) # Makes sure the directory holding the output file exists; creates @@ -146,7 +146,7 @@ def ValidateOutputDir(output_dir): def FuseGTestH(gtest_root, output_dir): """Scans folder gtest_root to generate gtest/gtest.h in output_dir.""" - output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w') + output_file = open(os.path.join(output_dir, GTEST_H_OUTPUT), 'w') processed_files = sets.Set() # Holds all gtest headers we've processed. def ProcessFile(gtest_header_path): @@ -159,7 +159,7 @@ def FuseGTestH(gtest_root, output_dir): processed_files.add(gtest_header_path) # Reads each line in the given gtest header. - for line in file(os.path.join(gtest_root, gtest_header_path), 'r'): + for line in open(os.path.join(gtest_root, gtest_header_path)): m = INCLUDE_GTEST_FILE_REGEX.match(line) if m: # It's '#include "gtest/..."' - let's process it recursively. @@ -187,7 +187,7 @@ def FuseGTestAllCcToFile(gtest_root, output_file): processed_files.add(gtest_source_file) # Reads each line in the given gtest source file. - for line in file(os.path.join(gtest_root, gtest_source_file), 'r'): + for line in open(os.path.join(gtest_root, gtest_source_file)): m = INCLUDE_GTEST_FILE_REGEX.match(line) if m: if 'include/' + m.group(1) == GTEST_SPI_H_SEED: @@ -203,7 +203,7 @@ def FuseGTestAllCcToFile(gtest_root, output_file): # There is no need to #include "gtest/gtest.h" more than once. if not GTEST_H_SEED in processed_files: processed_files.add(GTEST_H_SEED) - output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,)) + output_file.write('#include "{}"\n'.format(GTEST_H_OUTPUT)) else: m = INCLUDE_SRC_FILE_REGEX.match(line) if m: @@ -218,7 +218,7 @@ def FuseGTestAllCcToFile(gtest_root, output_file): def FuseGTestAllCc(gtest_root, output_dir): """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir.""" - output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w') + output_file = open(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w') FuseGTestAllCcToFile(gtest_root, output_file) output_file.close() @@ -242,7 +242,7 @@ def main(): # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR FuseGTest(sys.argv[1], sys.argv[2]) else: - print __doc__ + print(__doc__) sys.exit(1) diff --git a/media/webrtc/trunk/testing/gtest/scripts/gen_gtest_pred_impl.py b/media/webrtc/trunk/testing/gtest/scripts/gen_gtest_pred_impl.py index 3e7ab042ea..a34c529163 100755 --- a/media/webrtc/trunk/testing/gtest/scripts/gen_gtest_pred_impl.py +++ b/media/webrtc/trunk/testing/gtest/scripts/gen_gtest_pred_impl.py @@ -73,7 +73,7 @@ def HeaderPreamble(n): DEFS = { 'today' : time.strftime('%m/%d/%Y'), 'year' : time.strftime('%Y'), - 'command' : '%s %s' % (os.path.basename(sys.argv[0]), n), + 'command' : '{} {}'.format(os.path.basename(sys.argv[0]), n), 'n' : n } @@ -183,7 +183,7 @@ def Title(word): def OneTo(n): """Returns the list [1, 2, 3, ..., n].""" - return range(1, n + 1) + return list(range(1, n + 1)) def Iter(n, format, sep=''): @@ -303,13 +303,13 @@ def GenerateFile(path, content): """Given a file path and a content string, overwrites it with the given content.""" - print 'Updating file %s . . .' % path + print('Updating file %s . . .' % path) - f = file(path, 'w+') - print >>f, content, + f = open(path, 'w+') + print(content, end=' ', file=f) f.close() - print 'File %s has been updated.' % path + print('File %s has been updated.' % path) def GenerateHeader(n): @@ -329,7 +329,7 @@ def UnitTestPreamble(): DEFS = { 'today' : time.strftime('%m/%d/%Y'), 'year' : time.strftime('%Y'), - 'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]), + 'command' : '{} {}'.format(os.path.basename(sys.argv[0]), sys.argv[1]), } return ( @@ -525,9 +525,9 @@ class Predicate%(n)sTest : public testing::Test { // exactly once.""" tests += ''.join([""" - EXPECT_EQ(1, n%s_) << - "The predicate assertion didn't evaluate argument %s " - "exactly once.";""" % (i, i + 1) for i in OneTo(n)]) + EXPECT_EQ(1, n{}_) << + "The predicate assertion didn't evaluate argument {} " + "exactly once.";""".format(i, i + 1) for i in OneTo(n)]) tests += """ @@ -717,8 +717,8 @@ def _Main(): unit test.""" if len(sys.argv) != 2: - print __doc__ - print 'Author: ' + __author__ + print(__doc__) + print('Author: ' + __author__) sys.exit(1) n = int(sys.argv[1]) diff --git a/media/webrtc/trunk/testing/gtest/scripts/pump.py b/media/webrtc/trunk/testing/gtest/scripts/pump.py index 5efb653c20..fc7577bf8b 100755 --- a/media/webrtc/trunk/testing/gtest/scripts/pump.py +++ b/media/webrtc/trunk/testing/gtest/scripts/pump.py @@ -114,7 +114,7 @@ class Cursor: if self == Eof(): return 'EOF' else: - return '%s(%s)' % (self.line + 1, self.column) + return '{}({})'.format(self.line + 1, self.column) def __add__(self, offset): return Cursor(self.line, self.column + offset) @@ -150,7 +150,7 @@ class Token: self.token_type = token_type def __str__(self): - return 'Token @%s: \'%s\' type=%s' % ( + return 'Token @{}: \'{}\' type={}'.format( self.start, self.value, self.token_type) def Clone(self): @@ -246,7 +246,7 @@ def ParseToken(lines, pos, regex, token_type): if m and not m.start(): return MakeToken(lines, pos, pos + m.end(), token_type) else: - print 'ERROR: %s expected at %s.' % (token_type, pos) + print('ERROR: {} expected at {}.'.format(token_type, pos)) sys.exit(1) @@ -273,7 +273,7 @@ def SkipUntil(lines, pos, regex, token_type): if m: return pos + m.start() else: - print ('ERROR: %s expected on line %s after column %s.' % + print('ERROR: %s expected on line %s after column %s.' % (token_type, pos.line + 1, pos.column)) sys.exit(1) @@ -383,8 +383,7 @@ def Tokenize(s): """A generator that yields the tokens in the given string.""" if s != '': lines = s.splitlines(True) - for token in TokenizeLines(lines, Cursor(0, 0)): - yield token + yield from TokenizeLines(lines, Cursor(0, 0)) class CodeNode: @@ -453,8 +452,8 @@ def PushFront(a_list, elem): def PopToken(a_list, token_type=None): token = PopFront(a_list) if token_type is not None and token.token_type != token_type: - print 'ERROR: %s expected at %s' % (token_type, token.start) - print 'ERROR: %s found instead' % (token,) + print('ERROR: {} expected at {}'.format(token_type, token.start)) + print('ERROR: {} found instead'.format(token)) sys.exit(1) return token @@ -616,15 +615,15 @@ class Env: if identifier == var: return value - print 'ERROR: meta variable %s is undefined.' % (identifier,) + print('ERROR: meta variable {} is undefined.'.format(identifier)) sys.exit(1) def EvalExp(self, exp): try: result = eval(exp.python_exp) - except Exception, e: - print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) - print ('ERROR: failed to evaluate meta expression %s at %s' % + except Exception as e: + print('ERROR: caught exception {}: {}'.format(e.__class__.__name__, e)) + print('ERROR: failed to evaluate meta expression %s at %s' % (exp.python_exp, exp.token.start)) sys.exit(1) return result @@ -634,7 +633,7 @@ class Env: if identifier == var: return (lower, upper) - print 'ERROR: range %s is undefined.' % (identifier,) + print('ERROR: range {} is undefined.'.format(identifier)) sys.exit(1) @@ -688,14 +687,14 @@ def RunAtomicCode(env, node, output): RunCode(env.Clone(), node.else_branch, output) elif isinstance(node, ExpNode): value = env.EvalExp(node) - output.Append('%s' % (value,)) + output.Append('{}'.format(value)) elif isinstance(node, LiteralDollarNode): output.Append('$') elif isinstance(node, CodeNode): RunCode(env.Clone(), node, output) else: - print 'BAD' - print node + print('BAD') + print(node) sys.exit(1) @@ -830,19 +829,19 @@ def ConvertFromPumpSource(src_text): def main(argv): if len(argv) == 1: - print __doc__ + print(__doc__) sys.exit(1) file_path = argv[-1] - output_str = ConvertFromPumpSource(file(file_path, 'r').read()) + output_str = ConvertFromPumpSource(open(file_path).read()) if file_path.endswith('.pump'): output_file_path = file_path[:-5] else: output_file_path = '-' if output_file_path == '-': - print output_str, + print(output_str, end=' ') else: - output_file = file(output_file_path, 'w') + output_file = open(output_file_path, 'w') output_file.write('// This file was GENERATED by command:\n') output_file.write('// %s %s\n' % (os.path.basename(__file__), os.path.basename(file_path))) diff --git a/media/webrtc/trunk/testing/gtest/scripts/upload.py b/media/webrtc/trunk/testing/gtest/scripts/upload.py index 6e6f9a1471..5f55284505 100755 --- a/media/webrtc/trunk/testing/gtest/scripts/upload.py +++ b/media/webrtc/trunk/testing/gtest/scripts/upload.py @@ -31,7 +31,7 @@ against by using the '--rev' option. # This code is derived from appcfg.py in the App Engine SDK (open source), # and from ASPN recipe #146306. -import cookielib +import six.moves.http_cookiejar import getpass import logging import md5 @@ -42,9 +42,10 @@ import re import socket import subprocess import sys -import urllib -import urllib2 -import urlparse +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse +import six.moves.urllib.parse +import six try: import readline @@ -75,19 +76,19 @@ def GetEmail(prompt): last_email = "" if os.path.exists(last_email_file_name): try: - last_email_file = open(last_email_file_name, "r") + last_email_file = open(last_email_file_name) last_email = last_email_file.readline().strip("\n") last_email_file.close() prompt += " [%s]" % last_email - except IOError, e: + except OSError as e: pass - email = raw_input(prompt + ": ").strip() + email = input(prompt + ": ").strip() if email: try: last_email_file = open(last_email_file_name, "w") last_email_file.write(email) last_email_file.close() - except IOError, e: + except OSError as e: pass else: email = last_email @@ -103,25 +104,25 @@ def StatusUpdate(msg): msg: The string to print. """ if verbosity > 0: - print msg + print(msg) def ErrorExit(msg): """Print an error message to stderr and exit.""" - print >>sys.stderr, msg + print(msg, file=sys.stderr) sys.exit(1) -class ClientLoginError(urllib2.HTTPError): +class ClientLoginError(six.moves.urllib.error.HTTPError): """Raised to indicate there was an error authenticating with ClientLogin.""" def __init__(self, url, code, msg, headers, args): - urllib2.HTTPError.__init__(self, url, code, msg, headers, None) + six.moves.urllib.error.HTTPError.__init__(self, url, code, msg, headers, None) self.args = args self.reason = args["Error"] -class AbstractRpcServer(object): +class AbstractRpcServer: """Provides a common interface for a simple RPC server.""" def __init__(self, host, auth_function, host_override=None, extra_headers={}, @@ -162,10 +163,10 @@ class AbstractRpcServer(object): def _CreateRequest(self, url, data=None): """Creates a new urllib request.""" logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib2.Request(url, data=data) + req = six.moves.urllib.request.Request(url, data=data) if self.host_override: req.add_header("Host", self.host_override) - for key, value in self.extra_headers.iteritems(): + for key, value in self.extra_headers.items(): req.add_header(key, value) return req @@ -189,7 +190,7 @@ class AbstractRpcServer(object): account_type = "HOSTED" req = self._CreateRequest( url="https://www.google.com/accounts/ClientLogin", - data=urllib.urlencode({ + data=six.moves.urllib.parse.urlencode({ "Email": email, "Passwd": password, "service": "ah", @@ -203,7 +204,7 @@ class AbstractRpcServer(object): response_dict = dict(x.split("=") for x in response_body.split("\n") if x) return response_dict["Auth"] - except urllib2.HTTPError, e: + except six.moves.urllib.error.HTTPError as e: if e.code == 403: body = e.read() response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) @@ -225,14 +226,14 @@ class AbstractRpcServer(object): continue_location = "http://localhost/" args = {"continue": continue_location, "auth": auth_token} req = self._CreateRequest("http://%s/_ah/login?%s" % - (self.host, urllib.urlencode(args))) + (self.host, six.moves.urllib.parse.urlencode(args))) try: response = self.opener.open(req) - except urllib2.HTTPError, e: + except six.moves.urllib.error.HTTPError as e: response = e if (response.code != 302 or response.info()["location"] != continue_location): - raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, + raise six.moves.urllib.error.HTTPError(req.get_full_url(), response.code, response.msg, response.headers, response.fp) self.authenticated = True @@ -255,34 +256,34 @@ class AbstractRpcServer(object): credentials = self.auth_function() try: auth_token = self._GetAuthToken(credentials[0], credentials[1]) - except ClientLoginError, e: + except ClientLoginError as e: if e.reason == "BadAuthentication": - print >>sys.stderr, "Invalid username or password." + print("Invalid username or password.", file=sys.stderr) continue if e.reason == "CaptchaRequired": - print >>sys.stderr, ( + print(( "Please go to\n" "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.") + "and verify you are a human. Then try again."), file=sys.stderr) break if e.reason == "NotVerified": - print >>sys.stderr, "Account not verified." + print("Account not verified.", file=sys.stderr) break if e.reason == "TermsNotAgreed": - print >>sys.stderr, "User has not agreed to TOS." + print("User has not agreed to TOS.", file=sys.stderr) break if e.reason == "AccountDeleted": - print >>sys.stderr, "The user account has been deleted." + print("The user account has been deleted.", file=sys.stderr) break if e.reason == "AccountDisabled": - print >>sys.stderr, "The user account has been disabled." + print("The user account has been disabled.", file=sys.stderr) break if e.reason == "ServiceDisabled": - print >>sys.stderr, ("The user's access to the service has been " - "disabled.") + print(("The user's access to the service has been " + "disabled."), file=sys.stderr) break if e.reason == "ServiceUnavailable": - print >>sys.stderr, "The service is not available; try again later." + print("The service is not available; try again later.", file=sys.stderr) break raise self._GetAuthCookie(auth_token) @@ -317,9 +318,9 @@ class AbstractRpcServer(object): while True: tries += 1 args = dict(kwargs) - url = "http://%s%s" % (self.host, request_path) + url = "http://{}{}".format(self.host, request_path) if args: - url += "?" + urllib.urlencode(args) + url += "?" + six.moves.urllib.parse.urlencode(args) req = self._CreateRequest(url=url, data=payload) req.add_header("Content-Type", content_type) try: @@ -327,7 +328,7 @@ class AbstractRpcServer(object): response = f.read() f.close() return response - except urllib2.HTTPError, e: + except six.moves.urllib.error.HTTPError as e: if tries > 3: raise elif e.code == 401: @@ -346,7 +347,7 @@ class HttpRpcServer(AbstractRpcServer): def _Authenticate(self): """Save the cookie jar after authentication.""" - super(HttpRpcServer, self)._Authenticate() + super()._Authenticate() if self.save_cookies: StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) self.cookie_jar.save() @@ -357,35 +358,35 @@ class HttpRpcServer(AbstractRpcServer): Returns: A urllib2.OpenerDirector object. """ - opener = urllib2.OpenerDirector() - opener.add_handler(urllib2.ProxyHandler()) - opener.add_handler(urllib2.UnknownHandler()) - opener.add_handler(urllib2.HTTPHandler()) - opener.add_handler(urllib2.HTTPDefaultErrorHandler()) - opener.add_handler(urllib2.HTTPSHandler()) + opener = six.moves.urllib.request.OpenerDirector() + opener.add_handler(six.moves.urllib.request.ProxyHandler()) + opener.add_handler(six.moves.urllib.request.UnknownHandler()) + opener.add_handler(six.moves.urllib.request.HTTPHandler()) + opener.add_handler(six.moves.urllib.request.HTTPDefaultErrorHandler()) + opener.add_handler(six.moves.urllib.request.HTTPSHandler()) opener.add_handler(urllib2.HTTPErrorProcessor()) if self.save_cookies: self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) + self.cookie_jar = six.moves.http_cookiejar.MozillaCookieJar(self.cookie_file) if os.path.exists(self.cookie_file): try: self.cookie_jar.load() self.authenticated = True StatusUpdate("Loaded authentication cookies from %s" % self.cookie_file) - except (cookielib.LoadError, IOError): + except (six.moves.http_cookiejar.LoadError, OSError): # Failed to load cookies - just ignore them. pass else: # Create an empty cookie file with mode 600 - fd = os.open(self.cookie_file, os.O_CREAT, 0600) + fd = os.open(self.cookie_file, os.O_CREAT, 0o600) os.close(fd) # Always chmod the cookie file - os.chmod(self.cookie_file, 0600) + os.chmod(self.cookie_file, 0o600) else: # Don't save cookies across runs of update.py. - self.cookie_jar = cookielib.CookieJar() - opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) + self.cookie_jar = six.moves.http_cookiejar.CookieJar() + opener.add_handler(six.moves.urllib.request.HTTPCookieProcessor(self.cookie_jar)) return opener @@ -560,7 +561,7 @@ def RunShellWithReturnCode(command, print_output=False, line = p.stdout.readline() if not line: break - print line.strip("\n") + print(line.strip("\n")) output_array.append(line) output = "".join(output_array) else: @@ -568,7 +569,7 @@ def RunShellWithReturnCode(command, print_output=False, p.wait() errout = p.stderr.read() if print_output and errout: - print >>sys.stderr, errout + print(errout, file=sys.stderr) p.stdout.close() p.stderr.close() return output, p.returncode @@ -579,13 +580,13 @@ def RunShell(command, silent_ok=False, universal_newlines=True, data, retcode = RunShellWithReturnCode(command, print_output, universal_newlines) if retcode: - ErrorExit("Got error status from %s:\n%s" % (command, data)) + ErrorExit("Got error status from {}:\n{}".format(command, data)) if not silent_ok and not data: ErrorExit("No output from %s" % command) return data -class VersionControlSystem(object): +class VersionControlSystem: """Abstract base class providing an interface to the VCS.""" def __init__(self, options): @@ -614,11 +615,11 @@ class VersionControlSystem(object): """Show an "are you sure?" prompt if there are unknown files.""" unknown_files = self.GetUnknownFiles() if unknown_files: - print "The following files are not added to version control:" + print("The following files are not added to version control:") for line in unknown_files: - print line + print(line) prompt = "Are you sure to continue?(y/N) " - answer = raw_input(prompt).strip() + answer = input(prompt).strip() if answer != "y": ErrorExit("User aborted") @@ -670,13 +671,13 @@ class VersionControlSystem(object): else: type = "current" if len(content) > MAX_UPLOAD_SIZE: - print ("Not uploading the %s file for %s because it's too large." % + print("Not uploading the %s file for %s because it's too large." % (type, filename)) file_too_large = True content = "" checksum = md5.new(content).hexdigest() if options.verbose > 0 and not file_too_large: - print "Uploading %s file for %s" % (type, filename) + print("Uploading {} file for {}".format(type, filename)) url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) form_fields = [("filename", filename), ("status", status), @@ -722,7 +723,7 @@ class SubversionVCS(VersionControlSystem): """Implementation of the VersionControlSystem interface for Subversion.""" def __init__(self, options): - super(SubversionVCS, self).__init__(options) + super().__init__(options) if self.options.revision: match = re.match(r"(\d+)(:(\d+))?", self.options.revision) if not match: @@ -755,8 +756,8 @@ class SubversionVCS(VersionControlSystem): words = line.split() if len(words) == 2 and words[0] == "URL:": url = words[1] - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - username, netloc = urllib.splituser(netloc) + scheme, netloc, path, params, query, fragment = six.moves.urllib.parse.urlparse(url) + username, netloc = six.moves.urllib.parse.splituser(netloc) if username: logging.info("Removed username from base URL") if netloc.endswith("svn.python.org"): @@ -774,12 +775,12 @@ class SubversionVCS(VersionControlSystem): logging.info("Guessed CollabNet base = %s", base) elif netloc.endswith(".googlecode.com"): path = path + "/" - base = urlparse.urlunparse(("http", netloc, path, params, + base = six.moves.urllib.parse.urlunparse(("http", netloc, path, params, query, fragment)) logging.info("Guessed Google Code base = %s", base) else: path = path + "/" - base = urlparse.urlunparse((scheme, netloc, path, params, + base = six.moves.urllib.parse.urlunparse((scheme, netloc, path, params, query, fragment)) logging.info("Guessed base = %s", base) return base @@ -826,7 +827,7 @@ class SubversionVCS(VersionControlSystem): def repl(m): if m.group(2): - return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) + return "${}::{}$".format(m.group(1), " " * len(m.group(3))) return "$%s$" % m.group(1) keywords = [keyword for name in keyword_str.split(" ") @@ -918,7 +919,7 @@ class SubversionVCS(VersionControlSystem): (status[0] == " " and status[1] == "M")): # Property change. args = [] if self.options.revision: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + url = "{}/{}@{}".format(self.svn_base, filename, self.rev_start) else: # Don't change filename, it's needed later. url = filename @@ -941,7 +942,7 @@ class SubversionVCS(VersionControlSystem): if not self.rev_end: new_content = self.ReadFile(filename) else: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) + url = "{}/{}@{}".format(self.svn_base, filename, self.rev_end) new_content = RunShell(["svn", "cat", url], universal_newlines=True, silent_ok=True) else: @@ -957,7 +958,7 @@ class SubversionVCS(VersionControlSystem): if self.rev_start: # "svn cat -r REV delete_file.txt" doesn't work. cat requires # the full URL with "@REV" appended instead of using "-r" option. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + url = "{}/{}@{}".format(self.svn_base, filename, self.rev_start) base_content = RunShell(["svn", "cat", url], universal_newlines=universal_newlines, silent_ok=True) @@ -968,7 +969,7 @@ class SubversionVCS(VersionControlSystem): if not is_binary: args = [] if self.rev_start: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + url = "{}/{}@{}".format(self.svn_base, filename, self.rev_start) else: url = filename args += ["-r", "BASE"] @@ -986,7 +987,7 @@ class GitVCS(VersionControlSystem): """Implementation of the VersionControlSystem interface for Git.""" def __init__(self, options): - super(GitVCS, self).__init__(options) + super().__init__(options) # Map of filename -> hash of base file. self.base_hashes = {} @@ -1043,7 +1044,7 @@ class MercurialVCS(VersionControlSystem): """Implementation of the VersionControlSystem interface for Mercurial.""" def __init__(self, options, repo_dir): - super(MercurialVCS, self).__init__(options) + super().__init__(options) # Absolute path to repository (we can be in a subdir) self.repo_dir = os.path.normpath(repo_dir) # Compute the subdir @@ -1069,7 +1070,7 @@ class MercurialVCS(VersionControlSystem): svndiff = [] filecount = 0 for line in data.splitlines(): - m = re.match("diff --git a/(\S+) b/(\S+)", line) + m = re.match(r"diff --git a/(\S+) b/(\S+)", line) if m: # Modify line to make it look like as it comes from svn diff. # With this modification no changes on the server side are required @@ -1187,7 +1188,7 @@ def UploadSeparatePatches(issue, rpc_server, patchset, data, options): rv = [] for patch in patches: if len(patch[1]) > MAX_UPLOAD_SIZE: - print ("Not uploading the patch for " + patch[0] + + print("Not uploading the patch for " + patch[0] + " because the file is too large.") continue form_fields = [("filename", patch[0])] @@ -1196,7 +1197,7 @@ def UploadSeparatePatches(issue, rpc_server, patchset, data, options): files = [("data", "data.diff", patch[1])] ctype, body = EncodeMultipartFormData(form_fields, files) url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) - print "Uploading patch for " + patch[0] + print("Uploading patch for " + patch[0]) response_body = rpc_server.Send(url, body, content_type=ctype) lines = response_body.splitlines() if not lines or lines[0] != "OK": @@ -1223,7 +1224,8 @@ def GuessVCS(options): out, returncode = RunShellWithReturnCode(["hg", "root"]) if returncode == 0: return MercurialVCS(options, out.strip()) - except OSError, (errno, message): + except OSError as xxx_todo_changeme: + (errno, message) = xxx_todo_changeme.args if errno != 2: # ENOENT -- they don't have hg installed. raise @@ -1239,12 +1241,13 @@ def GuessVCS(options): "--is-inside-work-tree"]) if returncode == 0: return GitVCS(options) - except OSError, (errno, message): + except OSError as xxx_todo_changeme1: + (errno, message) = xxx_todo_changeme1.args if errno != 2: # ENOENT -- they don't have git installed. raise - ErrorExit(("Could not guess version control system. " - "Are you in a working copy directory?")) + ErrorExit("Could not guess version control system. " + "Are you in a working copy directory?") def RealMain(argv, data=None): @@ -1286,12 +1289,12 @@ def RealMain(argv, data=None): data = vcs.GenerateDiff(args) files = vcs.GetBaseFiles(data) if verbosity >= 1: - print "Upload server:", options.server, "(change with -s/--server)" + print("Upload server:", options.server, "(change with -s/--server)") if options.issue: prompt = "Message describing this patch set: " else: prompt = "New issue subject: " - message = options.message or raw_input(prompt).strip() + message = options.message or input(prompt).strip() if not message: ErrorExit("A non-empty message is required") rpc_server = GetRpcServer(options) @@ -1316,7 +1319,7 @@ def RealMain(argv, data=None): if options.description_file: if options.description: ErrorExit("Can't specify description and description_file") - file = open(options.description_file, 'r') + file = open(options.description_file) description = file.read() file.close() if description: @@ -1324,7 +1327,7 @@ def RealMain(argv, data=None): # Send a hash of all the base file so the server can determine if a copy # already exists in an earlier patchset. base_hashes = "" - for file, info in files.iteritems(): + for file, info in files.items(): if not info[0] is None: checksum = md5.new(info[0]).hexdigest() if base_hashes: @@ -1338,7 +1341,7 @@ def RealMain(argv, data=None): if not options.download_base: form_fields.append(("content_upload", "1")) if len(data) > MAX_UPLOAD_SIZE: - print "Patch is large, so uploading file patches separately." + print("Patch is large, so uploading file patches separately.") uploaded_diff_file = [] form_fields.append(("separate_patches", "1")) else: @@ -1378,7 +1381,7 @@ def main(): try: RealMain(sys.argv) except KeyboardInterrupt: - print + print() StatusUpdate("Interrupted.") sys.exit(1) diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_break_on_failure_unittest.py b/media/webrtc/trunk/testing/gtest/test/gtest_break_on_failure_unittest.py index c819183312..f36abe3381 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_break_on_failure_unittest.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_break_on_failure_unittest.py @@ -145,7 +145,7 @@ class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), should_or_not)) - self.assert_(has_seg_fault == expect_seg_fault, msg) + self.assertTrue(has_seg_fault == expect_seg_fault, msg) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_catch_exceptions_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_catch_exceptions_test.py index d7ef10eb06..2269adc55b 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_catch_exceptions_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_catch_exceptions_test.py @@ -74,21 +74,21 @@ if SUPPORTS_SEH_EXCEPTIONS: def TestSehExceptions(self, test_output): - self.assert_('SEH exception with code 0x2a thrown ' + self.assertTrue('SEH exception with code 0x2a thrown ' 'in the test fixture\'s constructor' in test_output) - self.assert_('SEH exception with code 0x2a thrown ' + self.assertTrue('SEH exception with code 0x2a thrown ' 'in the test fixture\'s destructor' in test_output) - self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' + self.assertTrue('SEH exception with code 0x2a thrown in SetUpTestCase()' in test_output) - self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' + self.assertTrue('SEH exception with code 0x2a thrown in TearDownTestCase()' in test_output) - self.assert_('SEH exception with code 0x2a thrown in SetUp()' + self.assertTrue('SEH exception with code 0x2a thrown in SetUp()' in test_output) - self.assert_('SEH exception with code 0x2a thrown in TearDown()' + self.assertTrue('SEH exception with code 0x2a thrown in TearDown()' in test_output) - self.assert_('SEH exception with code 0x2a thrown in the test body' + self.assertTrue('SEH exception with code 0x2a thrown in the test body' in test_output) def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): @@ -108,11 +108,11 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): """ def testCatchesCxxExceptionsInFixtureConstructor(self): - self.assert_('C++ exception with description ' + self.assertTrue('C++ exception with description ' '"Standard C++ exception" thrown ' 'in the test fixture\'s constructor' in EX_BINARY_OUTPUT) - self.assert_('unexpected' not in EX_BINARY_OUTPUT, + self.assertTrue('unexpected' not in EX_BINARY_OUTPUT, 'This failure belongs in this test only if ' '"CxxExceptionInConstructorTest" (no quotes) ' 'appears on the same line as words "called unexpectedly"') @@ -121,87 +121,87 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): EX_BINARY_OUTPUT): def testCatchesCxxExceptionsInFixtureDestructor(self): - self.assert_('C++ exception with description ' + self.assertTrue('C++ exception with description ' '"Standard C++ exception" thrown ' 'in the test fixture\'s destructor' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + self.assertTrue('CxxExceptionInDestructorTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInSetUpTestCase(self): - self.assert_('C++ exception with description "Standard C++ exception"' + self.assertTrue('C++ exception with description "Standard C++ exception"' ' thrown in SetUpTestCase()' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' + self.assertTrue('CxxExceptionInConstructorTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' + self.assertTrue('CxxExceptionInSetUpTestCaseTest constructor ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' + self.assertTrue('CxxExceptionInSetUpTestCaseTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' + self.assertTrue('CxxExceptionInSetUpTestCaseTest::SetUp() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' + self.assertTrue('CxxExceptionInSetUpTestCaseTest::TearDown() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTestCaseTest test body ' + self.assertTrue('CxxExceptionInSetUpTestCaseTest test body ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInTearDownTestCase(self): - self.assert_('C++ exception with description "Standard C++ exception"' + self.assertTrue('C++ exception with description "Standard C++ exception"' ' thrown in TearDownTestCase()' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInSetUp(self): - self.assert_('C++ exception with description "Standard C++ exception"' + self.assertTrue('C++ exception with description "Standard C++ exception"' ' thrown in SetUp()' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' + self.assertTrue('CxxExceptionInSetUpTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTest destructor ' + self.assertTrue('CxxExceptionInSetUpTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInSetUpTest::TearDown() ' + self.assertTrue('CxxExceptionInSetUpTest::TearDown() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('unexpected' not in EX_BINARY_OUTPUT, + self.assertTrue('unexpected' not in EX_BINARY_OUTPUT, 'This failure belongs in this test only if ' '"CxxExceptionInSetUpTest" (no quotes) ' 'appears on the same line as words "called unexpectedly"') def testCatchesCxxExceptionsInTearDown(self): - self.assert_('C++ exception with description "Standard C++ exception"' + self.assertTrue('C++ exception with description "Standard C++ exception"' ' thrown in TearDown()' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' + self.assertTrue('CxxExceptionInTearDownTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTearDownTest destructor ' + self.assertTrue('CxxExceptionInTearDownTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInTestBody(self): - self.assert_('C++ exception with description "Standard C++ exception"' + self.assertTrue('C++ exception with description "Standard C++ exception"' ' thrown in the test body' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' + self.assertTrue('CxxExceptionInTestBodyTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTestBodyTest destructor ' + self.assertTrue('CxxExceptionInTestBodyTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInTestBodyTest::TearDown() ' + self.assertTrue('CxxExceptionInTestBodyTest::TearDown() ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesNonStdCxxExceptions(self): - self.assert_('Unknown C++ exception thrown in the test body' + self.assertTrue('Unknown C++ exception thrown in the test body' in EX_BINARY_OUTPUT) def testUnhandledCxxExceptionsAbortTheProgram(self): @@ -214,9 +214,9 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): NO_CATCH_EXCEPTIONS_FLAG, FITLER_OUT_SEH_TESTS_FLAG]).output - self.assert_('Unhandled C++ exception terminating the program' + self.assertTrue('Unhandled C++ exception terminating the program' in uncaught_exceptions_ex_binary_output) - self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + self.assertTrue('unexpected' not in uncaught_exceptions_ex_binary_output) if __name__ == '__main__': diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_color_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_color_test.py index d02a53ed85..40e2e66eee 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_color_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_color_test.py @@ -62,7 +62,7 @@ def UsesColor(term, color_env_var, color_flag): if color_flag is None: args = [] else: - args = ['--%s=%s' % (COLOR_FLAG, color_flag)] + args = ['--{}={}'.format(COLOR_FLAG, color_flag)] p = gtest_test_utils.Subprocess([COMMAND] + args) return not p.exited or p.exit_code @@ -72,58 +72,58 @@ class GTestColorTest(gtest_test_utils.TestCase): """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" if not IS_WINDOWS: - self.assert_(not UsesColor('dumb', None, None)) - self.assert_(not UsesColor('emacs', None, None)) - self.assert_(not UsesColor('xterm-mono', None, None)) - self.assert_(not UsesColor('unknown', None, None)) - self.assert_(not UsesColor(None, None, None)) - self.assert_(UsesColor('linux', None, None)) - self.assert_(UsesColor('cygwin', None, None)) - self.assert_(UsesColor('xterm', None, None)) - self.assert_(UsesColor('xterm-color', None, None)) - self.assert_(UsesColor('xterm-256color', None, None)) + self.assertTrue(not UsesColor('dumb', None, None)) + self.assertTrue(not UsesColor('emacs', None, None)) + self.assertTrue(not UsesColor('xterm-mono', None, None)) + self.assertTrue(not UsesColor('unknown', None, None)) + self.assertTrue(not UsesColor(None, None, None)) + self.assertTrue(UsesColor('linux', None, None)) + self.assertTrue(UsesColor('cygwin', None, None)) + self.assertTrue(UsesColor('xterm', None, None)) + self.assertTrue(UsesColor('xterm-color', None, None)) + self.assertTrue(UsesColor('xterm-256color', None, None)) def testFlagOnly(self): """Tests the case when there's --gtest_color but not GTEST_COLOR.""" - self.assert_(not UsesColor('dumb', None, 'no')) - self.assert_(not UsesColor('xterm-color', None, 'no')) + self.assertTrue(not UsesColor('dumb', None, 'no')) + self.assertTrue(not UsesColor('xterm-color', None, 'no')) if not IS_WINDOWS: - self.assert_(not UsesColor('emacs', None, 'auto')) - self.assert_(UsesColor('xterm', None, 'auto')) - self.assert_(UsesColor('dumb', None, 'yes')) - self.assert_(UsesColor('xterm', None, 'yes')) + self.assertTrue(not UsesColor('emacs', None, 'auto')) + self.assertTrue(UsesColor('xterm', None, 'auto')) + self.assertTrue(UsesColor('dumb', None, 'yes')) + self.assertTrue(UsesColor('xterm', None, 'yes')) def testEnvVarOnly(self): """Tests the case when there's GTEST_COLOR but not --gtest_color.""" - self.assert_(not UsesColor('dumb', 'no', None)) - self.assert_(not UsesColor('xterm-color', 'no', None)) + self.assertTrue(not UsesColor('dumb', 'no', None)) + self.assertTrue(not UsesColor('xterm-color', 'no', None)) if not IS_WINDOWS: - self.assert_(not UsesColor('dumb', 'auto', None)) - self.assert_(UsesColor('xterm-color', 'auto', None)) - self.assert_(UsesColor('dumb', 'yes', None)) - self.assert_(UsesColor('xterm-color', 'yes', None)) + self.assertTrue(not UsesColor('dumb', 'auto', None)) + self.assertTrue(UsesColor('xterm-color', 'auto', None)) + self.assertTrue(UsesColor('dumb', 'yes', None)) + self.assertTrue(UsesColor('xterm-color', 'yes', None)) def testEnvVarAndFlag(self): """Tests the case when there are both GTEST_COLOR and --gtest_color.""" - self.assert_(not UsesColor('xterm-color', 'no', 'no')) - self.assert_(UsesColor('dumb', 'no', 'yes')) - self.assert_(UsesColor('xterm-color', 'no', 'auto')) + self.assertTrue(not UsesColor('xterm-color', 'no', 'no')) + self.assertTrue(UsesColor('dumb', 'no', 'yes')) + self.assertTrue(UsesColor('xterm-color', 'no', 'auto')) def testAliasesOfYesAndNo(self): """Tests using aliases in specifying --gtest_color.""" - self.assert_(UsesColor('dumb', None, 'true')) - self.assert_(UsesColor('dumb', None, 'YES')) - self.assert_(UsesColor('dumb', None, 'T')) - self.assert_(UsesColor('dumb', None, '1')) + self.assertTrue(UsesColor('dumb', None, 'true')) + self.assertTrue(UsesColor('dumb', None, 'YES')) + self.assertTrue(UsesColor('dumb', None, 'T')) + self.assertTrue(UsesColor('dumb', None, '1')) - self.assert_(not UsesColor('xterm', None, 'f')) - self.assert_(not UsesColor('xterm', None, 'false')) - self.assert_(not UsesColor('xterm', None, '0')) - self.assert_(not UsesColor('xterm', None, 'unknown')) + self.assertTrue(not UsesColor('xterm', None, 'f')) + self.assertTrue(not UsesColor('xterm', None, 'false')) + self.assertTrue(not UsesColor('xterm', None, '0')) + self.assertTrue(not UsesColor('xterm', None, 'unknown')) if __name__ == '__main__': diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_env_var_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_env_var_test.py index 4728bbc316..4e1c77fc2e 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_env_var_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_env_var_test.py @@ -47,8 +47,8 @@ environ = os.environ.copy() def AssertEq(expected, actual): if expected != actual: - print 'Expected: %s' % (expected,) - print ' Actual: %s' % (actual,) + print('Expected: {}'.format(expected)) + print(' Actual: {}'.format(actual)) raise AssertionError diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_filter_unittest.py b/media/webrtc/trunk/testing/gtest/test/gtest_filter_unittest.py index 0d1a770058..df0165cd84 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_filter_unittest.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_filter_unittest.py @@ -231,10 +231,10 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): """Asserts that two sets are equal.""" for elem in lhs: - self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) + self.assertTrue(elem in rhs, '{} in {}'.format(elem, rhs)) for elem in rhs: - self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + self.assertTrue(elem in lhs, '{} in {}'.format(elem, lhs)) def AssertPartitionIsValid(self, set_var, list_of_sets): """Asserts that list_of_sets is a valid partition of set_var.""" @@ -279,7 +279,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): if gtest_filter is None: args = [] else: - args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] + args = ['--{}={}'.format(FILTER_FLAG, gtest_filter)] tests_run = RunAndExtractTestList(args)[0] self.AssertSetEqual(tests_run, tests_to_run) @@ -338,7 +338,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): # Construct the command line. args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] if gtest_filter is not None: - args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) + args.append('--{}={}'.format(FILTER_FLAG, gtest_filter)) tests_run = RunAndExtractTestList(args)[0] self.AssertSetEqual(tests_run, tests_to_run) @@ -564,7 +564,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): """Tests that the filter flag overrides the filtering env. variable.""" SetEnvVar(FILTER_ENV_VAR, 'Foo*') - args = ['--%s=%s' % (FILTER_FLAG, '*One')] + args = ['--{}={}'.format(FILTER_FLAG, '*One')] tests_run = RunAndExtractTestList(args)[0] SetEnvVar(FILTER_ENV_VAR, None) @@ -575,13 +575,13 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), 'shard_status_file') - self.assert_(not os.path.exists(shard_status_file)) + self.assertTrue(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} try: InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) finally: - self.assert_(os.path.exists(shard_status_file)) + self.assertTrue(os.path.exists(shard_status_file)) os.remove(shard_status_file) def testShardStatusFileIsCreatedWithListTests(self): @@ -589,7 +589,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), 'shard_status_file2') - self.assert_(not os.path.exists(shard_status_file)) + self.assertTrue(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} try: @@ -599,12 +599,12 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): finally: # This assertion ensures that Google Test enumerated the tests as # opposed to running them. - self.assert_('[==========]' not in output, + self.assertTrue('[==========]' not in output, 'Unexpected output during test enumeration.\n' 'Please ensure that LIST_TESTS_FLAG is assigned the\n' 'correct flag value for listing Google Test tests.') - self.assert_(os.path.exists(shard_status_file)) + self.assertTrue(os.path.exists(shard_status_file)) os.remove(shard_status_file) if SUPPORTS_DEATH_TESTS: diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_help_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_help_test.py index 093c838d9e..32ff46ca53 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_help_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_help_test.py @@ -109,18 +109,18 @@ class GTestHelpTest(gtest_test_utils.TestCase): """ exit_code, output = RunWithFlag(flag) - self.assertEquals(0, exit_code) - self.assert_(HELP_REGEX.search(output), output) + self.assertEqual(0, exit_code) + self.assertTrue(HELP_REGEX.search(output), output) if IS_LINUX: - self.assert_(STREAM_RESULT_TO_FLAG in output, output) + self.assertTrue(STREAM_RESULT_TO_FLAG in output, output) else: - self.assert_(STREAM_RESULT_TO_FLAG not in output, output) + self.assertTrue(STREAM_RESULT_TO_FLAG not in output, output) if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: - self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + self.assertTrue(DEATH_TEST_STYLE_FLAG in output, output) else: - self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) + self.assertTrue(DEATH_TEST_STYLE_FLAG not in output, output) def TestNonHelpFlag(self, flag): """Verifies correct behavior when no help flag is specified. @@ -133,8 +133,8 @@ class GTestHelpTest(gtest_test_utils.TestCase): """ exit_code, output = RunWithFlag(flag) - self.assert_(exit_code != 0) - self.assert_(not HELP_REGEX.search(output), output) + self.assertTrue(exit_code != 0) + self.assertTrue(not HELP_REGEX.search(output), output) def testPrintsHelpWithFullFlag(self): self.TestHelpFlag('--help') diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_list_tests_unittest.py b/media/webrtc/trunk/testing/gtest/test/gtest_list_tests_unittest.py index ce8c3ef05f..1d3ce746ca 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_list_tests_unittest.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_list_tests_unittest.py @@ -136,9 +136,9 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase): (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)) if expected_output is not None: - self.assert_(output == expected_output, msg) + self.assertTrue(output == expected_output, msg) else: - self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg) + self.assertTrue(output != EXPECTED_OUTPUT_NO_FILTER, msg) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_output_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_output_test.py index 72b3ae0084..9a684489df 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_output_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_output_test.py @@ -141,7 +141,7 @@ def NormalizeToCurrentPlatform(test_output): if IS_WINDOWS: # Removes the color information that is not present on Windows. - test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) + test_output = re.sub('\x1b\\[(0;3\\d)?m', '', test_output) # Changes failure message headers into the Windows format. test_output = re.sub(r': Failure\n', r': error: ', test_output) # Changes file(line_number) to file:line_number. @@ -180,7 +180,7 @@ def RemoveMatchingTests(test_output, pattern): """ test_output = re.sub( - r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + r'.*\[ RUN \] .*{}(.|\n)*?\[( FAILED | OK )\] .*{}.*\n'.format( pattern, pattern), '', test_output) diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_shuffle_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_shuffle_test.py index d3e57809de..e084a335ab 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_shuffle_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_shuffle_test.py @@ -60,11 +60,11 @@ def AlsoRunDisabledTestsFlag(): def FilterFlag(test_filter): - return '--gtest_filter=%s' % (test_filter,) + return '--gtest_filter={}'.format(test_filter) def RepeatFlag(n): - return '--gtest_repeat=%s' % (n,) + return '--gtest_repeat={}'.format(n) def ShuffleFlag(): @@ -72,7 +72,7 @@ def ShuffleFlag(): def RandomSeedFlag(n): - return '--gtest_random_seed=%s' % (n,) + return '--gtest_random_seed={}'.format(n) def RunAndReturnOutput(extra_env, args): @@ -180,66 +180,66 @@ class GTestShuffleUnitTest(gtest_test_utils.TestCase): self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) def testShuffleChangesTestOrder(self): - self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) - self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) - self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + self.assertTrue(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assertTrue(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assertTrue(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, SHUFFLED_FILTERED_TESTS) - self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + self.assertTrue(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, SHUFFLED_SHARDED_TESTS) def testShuffleChangesTestCaseOrder(self): - self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + self.assertTrue(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), GetTestCases(SHUFFLED_ALL_TESTS)) - self.assert_( + self.assertTrue( GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), GetTestCases(SHUFFLED_ACTIVE_TESTS)) - self.assert_( + self.assertTrue( GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), GetTestCases(SHUFFLED_FILTERED_TESTS)) - self.assert_( + self.assertTrue( GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), GetTestCases(SHUFFLED_SHARDED_TESTS)) def testShuffleDoesNotRepeatTest(self): for test in SHUFFLED_ALL_TESTS: self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), - '%s appears more than once' % (test,)) + '{} appears more than once'.format(test)) for test in SHUFFLED_ACTIVE_TESTS: self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), - '%s appears more than once' % (test,)) + '{} appears more than once'.format(test)) for test in SHUFFLED_FILTERED_TESTS: self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), - '%s appears more than once' % (test,)) + '{} appears more than once'.format(test)) for test in SHUFFLED_SHARDED_TESTS: self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), - '%s appears more than once' % (test,)) + '{} appears more than once'.format(test)) def testShuffleDoesNotCreateNewTest(self): for test in SHUFFLED_ALL_TESTS: - self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + self.assertTrue(test in ALL_TESTS, '{} is an invalid test'.format(test)) for test in SHUFFLED_ACTIVE_TESTS: - self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + self.assertTrue(test in ACTIVE_TESTS, '{} is an invalid test'.format(test)) for test in SHUFFLED_FILTERED_TESTS: - self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + self.assertTrue(test in FILTERED_TESTS, '{} is an invalid test'.format(test)) for test in SHUFFLED_SHARDED_TESTS: - self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + self.assertTrue(test in SHARDED_TESTS, '{} is an invalid test'.format(test)) def testShuffleIncludesAllTests(self): for test in ALL_TESTS: - self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + self.assertTrue(test in SHUFFLED_ALL_TESTS, '{} is missing'.format(test)) for test in ACTIVE_TESTS: - self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + self.assertTrue(test in SHUFFLED_ACTIVE_TESTS, '{} is missing'.format(test)) for test in FILTERED_TESTS: - self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + self.assertTrue(test in SHUFFLED_FILTERED_TESTS, '{} is missing'.format(test)) for test in SHARDED_TESTS: - self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + self.assertTrue(test in SHUFFLED_SHARDED_TESTS, '{} is missing'.format(test)) def testShuffleLeavesDeathTestsAtFront(self): non_death_test_found = False for test in SHUFFLED_ACTIVE_TESTS: if 'DeathTest.' in test: - self.assert_(not non_death_test_found, - '%s appears after a non-death test' % (test,)) + self.assertTrue(not non_death_test_found, + '{} appears after a non-death test'.format(test)) else: non_death_test_found = True @@ -296,11 +296,11 @@ class GTestShuffleUnitTest(gtest_test_utils.TestCase): GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) - self.assert_(tests_in_iteration1 != tests_in_iteration2, + self.assertTrue(tests_in_iteration1 != tests_in_iteration2, tests_in_iteration1) - self.assert_(tests_in_iteration1 != tests_in_iteration3, + self.assertTrue(tests_in_iteration1 != tests_in_iteration3, tests_in_iteration1) - self.assert_(tests_in_iteration2 != tests_in_iteration3, + self.assertTrue(tests_in_iteration2 != tests_in_iteration3, tests_in_iteration2) def testShuffleShardedTestsPreservesPartition(self): diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_test_utils.py b/media/webrtc/trunk/testing/gtest/test/gtest_test_utils.py index 6dd8db4bf0..39a6031cd5 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_test_utils.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_test_utils.py @@ -163,7 +163,7 @@ def GetTestExecutablePath(executable_name, build_dir=None): 'Unable to find the test binary. Please make sure to provide path\n' 'to the binary via the --build_dir flag or the BUILD_DIR\n' 'environment variable.') - print >> sys.stderr, message + print(message, file=sys.stderr) sys.exit(1) return path diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_throw_on_failure_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_throw_on_failure_test.py index 5678ffeaf6..318e6306c5 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_throw_on_failure_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_throw_on_failure_test.py @@ -70,7 +70,7 @@ def SetEnvVar(env_var, value): def Run(command): """Runs a command; returns True/False if its exit code is/isn't 0.""" - print 'Running "%s". . .' % ' '.join(command) + print('Running "%s". . .' % ' '.join(command)) p = gtest_test_utils.Subprocess(command) return p.exited and p.exit_code == 0 @@ -123,7 +123,7 @@ class ThrowOnFailureTest(gtest_test_utils.TestCase): 'exit code.' % (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), should_or_not)) - self.assert_(failed == should_fail, msg) + self.assertTrue(failed == should_fail, msg) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_uninitialized_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_uninitialized_test.py index 6ae57eeeda..9dd807df2a 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_uninitialized_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_uninitialized_test.py @@ -46,8 +46,8 @@ def Assert(condition): def AssertEq(expected, actual): if expected != actual: - print 'Expected: %s' % (expected,) - print ' Actual: %s' % (actual,) + print('Expected: {}'.format(expected)) + print(' Actual: {}'.format(actual)) raise AssertionError diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_xml_outfiles_test.py b/media/webrtc/trunk/testing/gtest/test/gtest_xml_outfiles_test.py index 524e437e6c..a36c552df2 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_xml_outfiles_test.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_xml_outfiles_test.py @@ -78,15 +78,15 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): def DeleteFilesAndDir(self): try: os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) - except os.error: + except OSError: pass try: os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) - except os.error: + except OSError: pass try: os.rmdir(self.output_dir_) - except os.error: + except OSError: pass def testOutfile1(self): @@ -100,8 +100,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] p = gtest_test_utils.Subprocess(command, working_dir=gtest_test_utils.GetTempDir()) - self.assert_(p.exited) - self.assertEquals(0, p.exit_code) + self.assertTrue(p.exited) + self.assertEqual(0, p.exit_code) # TODO(wan@google.com): libtool causes the built test binary to be # named lt-gtest_xml_outfiles_test_ instead of @@ -112,7 +112,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): output_file1 = os.path.join(self.output_dir_, output_file_name1) output_file_name2 = 'lt-' + output_file_name1 output_file2 = os.path.join(self.output_dir_, output_file_name2) - self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + self.assertTrue(os.path.isfile(output_file1) or os.path.isfile(output_file2), output_file1) expected = minidom.parseString(expected_xml) diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py b/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py index 8cdfb56b68..8dcce1cffa 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py @@ -65,7 +65,7 @@ EXPECTED_NON_EMPTY_XML = """ +Expected: 1{stack}]]> @@ -73,10 +73,10 @@ Expected: 1%(stack)s]]> +Expected: 1{stack}]]> +Expected: 2{stack}]]> @@ -84,14 +84,14 @@ Expected: 2%(stack)s]]> ]]>%(stack)s]]> +XML output: ]]>{stack}]]> +Invalid characters in brackets []{stack}]]> @@ -126,7 +126,7 @@ Invalid characters in brackets []%(stack)s]]> -""" % {'stack': STACK_TRACE_TEMPLATE} +""".format(stack=STACK_TRACE_TEMPLATE) EXPECTED_EMPTY_XML = """ @@ -199,16 +199,16 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): 'gtest_no_test_unittest') try: os.remove(output_file) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: raise p = gtest_test_utils.Subprocess( [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], working_dir=gtest_test_utils.GetTempDir()) - self.assert_(p.exited) - self.assertEquals(0, p.exit_code) - self.assert_(os.path.isfile(output_file)) + self.assertTrue(p.exited) + self.assertEqual(0, p.exit_code) + self.assertTrue(os.path.isfile(output_file)) def testSuppressedXmlOutput(self): """ @@ -222,7 +222,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): os.remove(xml_path) command = [GTEST_PROGRAM_PATH, - '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), + '{}=xml:{}'.format(GTEST_OUTPUT_FLAG, xml_path), '--shut_down_xml'] p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: @@ -231,13 +231,13 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): p.terminated_by_signal, '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) else: - self.assert_(p.exited) - self.assertEquals(1, p.exit_code, + self.assertTrue(p.exited) + self.assertEqual(1, p.exit_code, "'%s' exited with code %s, which doesn't match " 'the expected exit code %s.' % (command, p.exit_code, 1)) - self.assert_(not os.path.isfile(xml_path)) + self.assertTrue(not os.path.isfile(xml_path)) def _GetXmlOutput(self, gtest_prog_name, expected_exit_code): """ @@ -248,14 +248,14 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): gtest_prog_name + 'out.xml') gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) - command = [gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + command = [gtest_prog_path, '{}=xml:{}'.format(GTEST_OUTPUT_FLAG, xml_path)] p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: - self.assert_(False, + self.assertTrue(False, '%s was killed by signal %d' % (gtest_prog_name, p.signal)) else: - self.assert_(p.exited) - self.assertEquals(expected_exit_code, p.exit_code, + self.assertTrue(p.exited) + self.assertEqual(expected_exit_code, p.exit_code, "'%s' exited with code %s, which doesn't match " 'the expected exit code %s.' % (command, p.exit_code, expected_exit_code)) diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_xml_test_utils.py b/media/webrtc/trunk/testing/gtest/test/gtest_xml_test_utils.py index 0e5a1089d1..1542337f6b 100755 --- a/media/webrtc/trunk/testing/gtest/test/gtest_xml_test_utils.py +++ b/media/webrtc/trunk/testing/gtest/test/gtest_xml_test_utils.py @@ -68,37 +68,37 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): """ if expected_node.nodeType == Node.CDATA_SECTION_NODE: - self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) - self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + self.assertEqual(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEqual(expected_node.nodeValue, actual_node.nodeValue) return - self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) - self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) - self.assertEquals(expected_node.tagName, actual_node.tagName) + self.assertEqual(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEqual(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEqual(expected_node.tagName, actual_node.tagName) expected_attributes = expected_node.attributes actual_attributes = actual_node .attributes - self.assertEquals( + self.assertEqual( expected_attributes.length, actual_attributes.length, 'attribute numbers differ in element ' + actual_node.tagName) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) - self.assert_( + self.assertTrue( actual_attr is not None, 'expected attribute %s not found in element %s' % (expected_attr.name, actual_node.tagName)) - self.assertEquals(expected_attr.value, actual_attr.value, + self.assertEqual(expected_attr.value, actual_attr.value, ' values of attribute %s in element %s differ' % (expected_attr.name, actual_node.tagName)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) - self.assertEquals( + self.assertEqual( len(expected_children), len(actual_children), 'number of child elements differ in element ' + actual_node.tagName) - for child_id, child in expected_children.iteritems(): - self.assert_(child_id in actual_children, + for child_id, child in expected_children.items(): + self.assertTrue(child_id in actual_children, '<%s> is not in <%s> (in element %s)' % (child_id, actual_children, actual_node.tagName)) self.AssertEquivalentNodes(child, actual_children[child_id]) @@ -126,10 +126,10 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): children = {} for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: - self.assert_(child.tagName in self.identifying_attribute, + self.assertTrue(child.tagName in self.identifying_attribute, 'Encountered unknown element <%s>' % child.tagName) childID = child.getAttribute(self.identifying_attribute[child.tagName]) - self.assert_(childID not in children) + self.assertTrue(childID not in children) children[childID] = child elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: if 'detail' not in children: diff --git a/media/webrtc/trunk/testing/gtest/xcode/Scripts/versiongenerate.py b/media/webrtc/trunk/testing/gtest/xcode/Scripts/versiongenerate.py index 81de8c96ac..edbbba669d 100644 --- a/media/webrtc/trunk/testing/gtest/xcode/Scripts/versiongenerate.py +++ b/media/webrtc/trunk/testing/gtest/xcode/Scripts/versiongenerate.py @@ -54,14 +54,14 @@ import re # Read the command line argument (the output directory for Version.h) if (len(sys.argv) < 3): - print "Usage: versiongenerate.py input_dir output_dir" + print("Usage: versiongenerate.py input_dir output_dir") sys.exit(1) else: input_dir = sys.argv[1] output_dir = sys.argv[2] # Read the first 1024 characters of the configure.ac file -config_file = open("%s/configure.ac" % input_dir, 'r') +config_file = open("%s/configure.ac" % input_dir) buffer_size = 1024 opening_string = config_file.read(buffer_size) config_file.close() @@ -91,10 +91,10 @@ file_data = """// // this, we are not not restricted to C-syntax nor are we using include guards. // -#define GTEST_VERSIONINFO_SHORT %s.%s -#define GTEST_VERSIONINFO_LONG %s.%s.%s +#define GTEST_VERSIONINFO_SHORT {}.{} +#define GTEST_VERSIONINFO_LONG {}.{}.{} -""" % (major_version, minor_version, major_version, minor_version, fix_version) +""".format(major_version, minor_version, major_version, minor_version, fix_version) version_file = open("%s/Version.h" % output_dir, 'w') version_file.write(file_data) version_file.close() diff --git a/media/webrtc/trunk/tools/gyp/PRESUBMIT.py b/media/webrtc/trunk/tools/gyp/PRESUBMIT.py index dde025383c..8180fe5f95 100644 --- a/media/webrtc/trunk/tools/gyp/PRESUBMIT.py +++ b/media/webrtc/trunk/tools/gyp/PRESUBMIT.py @@ -85,7 +85,7 @@ def CheckChangeOnCommit(input_api, output_api): # Accept any year number from 2009 to the current year. current_year = int(input_api.time.strftime('%Y')) - allowed_years = (str(s) for s in reversed(xrange(2009, current_year + 1))) + allowed_years = (str(s) for s in reversed(range(2009, current_year + 1))) years_re = '(' + '|'.join(allowed_years) + ')' # The (c) is deprecated, but tolerate it until it's removed from all files. diff --git a/media/webrtc/trunk/tools/gyp/buildbot/buildbot_run.py b/media/webrtc/trunk/tools/gyp/buildbot/buildbot_run.py index 9a2b71f1b3..964ed26bf0 100755 --- a/media/webrtc/trunk/tools/gyp/buildbot/buildbot_run.py +++ b/media/webrtc/trunk/tools/gyp/buildbot/buildbot_run.py @@ -24,14 +24,14 @@ def CallSubProcess(*args, **kwargs): with open(os.devnull) as devnull_fd: retcode = subprocess.call(stdin=devnull_fd, *args, **kwargs) if retcode != 0: - print '@@@STEP_EXCEPTION@@@' + print('@@@STEP_EXCEPTION@@@') sys.exit(1) def PrepareCmake(): """Build CMake 2.8.8 since the version in Precise is 2.8.7.""" if os.environ['BUILDBOT_CLOBBER'] == '1': - print '@@@BUILD_STEP Clobber CMake checkout@@@' + print('@@@BUILD_STEP Clobber CMake checkout@@@') shutil.rmtree(CMAKE_DIR) # We always build CMake 2.8.8, so no need to do anything @@ -39,10 +39,10 @@ def PrepareCmake(): if os.path.isdir(CMAKE_DIR): return - print '@@@BUILD_STEP Initialize CMake checkout@@@' + print('@@@BUILD_STEP Initialize CMake checkout@@@') os.mkdir(CMAKE_DIR) - print '@@@BUILD_STEP Sync CMake@@@' + print('@@@BUILD_STEP Sync CMake@@@') CallSubProcess( ['git', 'clone', '--depth', '1', @@ -53,7 +53,7 @@ def PrepareCmake(): CMAKE_DIR], cwd=CMAKE_DIR) - print '@@@BUILD_STEP Build CMake@@@' + print('@@@BUILD_STEP Build CMake@@@') CallSubProcess( ['/bin/bash', 'bootstrap', '--prefix=%s' % CMAKE_DIR], cwd=CMAKE_DIR) @@ -74,7 +74,7 @@ def GypTestFormat(title, format=None, msvs_version=None, tests=[]): if not format: format = title - print '@@@BUILD_STEP ' + title + '@@@' + print('@@@BUILD_STEP ' + title + '@@@') sys.stdout.flush() env = os.environ.copy() if msvs_version: @@ -89,17 +89,17 @@ def GypTestFormat(title, format=None, msvs_version=None, tests=[]): retcode = subprocess.call(command, cwd=ROOT_DIR, env=env, shell=True) if retcode: # Emit failure tag, and keep going. - print '@@@STEP_FAILURE@@@' + print('@@@STEP_FAILURE@@@') return 1 return 0 def GypBuild(): # Dump out/ directory. - print '@@@BUILD_STEP cleanup@@@' - print 'Removing %s...' % OUT_DIR + print('@@@BUILD_STEP cleanup@@@') + print('Removing %s...' % OUT_DIR) shutil.rmtree(OUT_DIR, ignore_errors=True) - print 'Done.' + print('Done.') retcode = 0 if sys.platform.startswith('linux'): @@ -128,7 +128,7 @@ def GypBuild(): # after the build proper that could be used for cumulative failures), # use that instead of this. This isolates the final return value so # that it isn't misattributed to the last stage. - print '@@@BUILD_STEP failures@@@' + print('@@@BUILD_STEP failures@@@') sys.exit(retcode) diff --git a/media/webrtc/trunk/tools/gyp/gyptest.py b/media/webrtc/trunk/tools/gyp/gyptest.py index 8e4fc47d5c..b45c287717 100755 --- a/media/webrtc/trunk/tools/gyp/gyptest.py +++ b/media/webrtc/trunk/tools/gyp/gyptest.py @@ -13,7 +13,7 @@ import optparse import subprocess import sys -class CommandRunner(object): +class CommandRunner: """ Executor class for commands, including "commands" implemented by Python functions. @@ -51,7 +51,7 @@ class CommandRunner(object): if type(command) == type(()): func = command[0] args = command[1:] - s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args))) + s = '{}({})'.format(func.__name__, ', '.join(map(repr, args))) if type(command) == type([]): # TODO: quote arguments containing spaces # TODO: handle meta characters? @@ -69,7 +69,7 @@ class CommandRunner(object): """ if not self.active: return 0 - if type(command) == type(''): + if type(command) == str: command = self.subst(command) cmdargs = shlex.split(command) if cmdargs[0] == 'cd': @@ -117,7 +117,7 @@ class CommandRunner(object): return self.execute(command, stdout, stderr) -class Unbuffered(object): +class Unbuffered: def __init__(self, fp): self.fp = fp def write(self, arg): @@ -190,13 +190,13 @@ def main(argv=None): tests.extend(find_all_gyptest_files(os.path.normpath(arg))) else: if not is_test_name(os.path.basename(arg)): - print >>sys.stderr, arg, 'is not a valid gyp test name.' + print(arg, 'is not a valid gyp test name.', file=sys.stderr) sys.exit(1) tests.append(arg) if opts.list: for test in tests: - print test + print(test) sys.exit(0) CommandRunner.verbose = not opts.quiet diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSNew.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSNew.py index 593f0e5b0b..71730e4ebb 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSNew.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSNew.py @@ -59,7 +59,7 @@ def MakeGuid(name, seed='msvs_new'): #------------------------------------------------------------------------------ -class MSVSSolutionEntry(object): +class MSVSSolutionEntry: def __cmp__(self, other): # Sort by name then guid (so things are in order on vs2008). return cmp((self.name, self.get_guid()), (other.name, other.get_guid())) @@ -172,7 +172,7 @@ class MSVSProject(MSVSSolutionEntry): #------------------------------------------------------------------------------ -class MSVSSolution(object): +class MSVSSolution: """Visual Studio solution.""" def __init__(self, path, version, entries=None, variants=None, @@ -250,7 +250,7 @@ class MSVSSolution(object): # msbuild does not accept an empty folder_name. # use '.' in case relative_path is empty. folder_name = relative_path.replace('/', '\\') or '.' - f.write('Project("%s") = "%s", "%s", "%s"\r\n' % ( + f.write('Project("{}") = "{}", "{}", "{}"\r\n'.format( e.entry_type_guid, # Entry type GUID e.name, # Folder name folder_name, # Folder name (again) @@ -268,14 +268,14 @@ class MSVSSolution(object): if e.items: f.write('\tProjectSection(SolutionItems) = preProject\r\n') for i in e.items: - f.write('\t\t%s = %s\r\n' % (i, i)) + f.write('\t\t{} = {}\r\n'.format(i, i)) f.write('\tEndProjectSection\r\n') if isinstance(e, MSVSProject): if e.dependencies: f.write('\tProjectSection(ProjectDependencies) = postProject\r\n') for d in e.dependencies: - f.write('\t\t%s = %s\r\n' % (d.get_guid(), d.get_guid())) + f.write('\t\t{} = {}\r\n'.format(d.get_guid(), d.get_guid())) f.write('\tEndProjectSection\r\n') f.write('EndProject\r\n') @@ -286,7 +286,7 @@ class MSVSSolution(object): # Configurations (variants) f.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n') for v in self.variants: - f.write('\t\t%s = %s\r\n' % (v, v)) + f.write('\t\t{} = {}\r\n'.format(v, v)) f.write('\tEndGlobalSection\r\n') # Sort config guids for easier diffing of solution changes. @@ -304,14 +304,14 @@ class MSVSSolution(object): nv = config_guids_overrides[g].get(v, v) # Pick which project configuration to build for this solution # configuration. - f.write('\t\t%s.%s.ActiveCfg = %s\r\n' % ( + f.write('\t\t{}.{}.ActiveCfg = {}\r\n'.format( g, # Project GUID v, # Solution build configuration nv, # Project build config for that solution config )) # Enable project in this solution configuration. - f.write('\t\t%s.%s.Build.0 = %s\r\n' % ( + f.write('\t\t{}.{}.Build.0 = {}\r\n'.format( g, # Project GUID v, # Solution build configuration nv, # Project build config for that solution config @@ -332,7 +332,7 @@ class MSVSSolution(object): if not isinstance(e, MSVSFolder): continue # Does not apply to projects, only folders for subentry in e.entries: - f.write('\t\t%s = %s\r\n' % (subentry.get_guid(), e.get_guid())) + f.write('\t\t{} = {}\r\n'.format(subentry.get_guid(), e.get_guid())) f.write('\tEndGlobalSection\r\n') f.write('EndGlobal\r\n') diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSProject.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSProject.py index db1ceede34..0b74fb8996 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSProject.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSProject.py @@ -10,7 +10,7 @@ import gyp.easy_xml as easy_xml #------------------------------------------------------------------------------ -class Tool(object): +class Tool: """Visual Studio tool.""" def __init__(self, name, attrs=None): @@ -31,7 +31,7 @@ class Tool(object): """ return ['Tool', self._attrs] -class Filter(object): +class Filter: """Visual Studio filter - that is, a virtual folder.""" def __init__(self, name, contents=None): @@ -48,7 +48,7 @@ class Filter(object): #------------------------------------------------------------------------------ -class Writer(object): +class Writer: """Visual Studio XML project writer.""" def __init__(self, project_path, version, name, guid=None, platforms=None): diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSSettings.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSSettings.py index 8ae19180ea..993c2f0115 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSSettings.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSSettings.py @@ -32,7 +32,7 @@ _msvs_to_msbuild_converters = {} _msbuild_name_of_tool = {} -class _Tool(object): +class _Tool: """Represents a tool used by MSVS or MSBuild. Attributes: @@ -64,7 +64,7 @@ def _GetMSBuildToolSettings(msbuild_settings, tool): return msbuild_settings.setdefault(tool.msbuild_name, {}) -class _Type(object): +class _Type: """Type of settings (Base class).""" def ValidateMSVS(self, value): @@ -106,11 +106,11 @@ class _String(_Type): """A setting that's just a string.""" def ValidateMSVS(self, value): - if not isinstance(value, basestring): + if not isinstance(value, str): raise ValueError('expected string; got %r' % value) def ValidateMSBuild(self, value): - if not isinstance(value, basestring): + if not isinstance(value, str): raise ValueError('expected string; got %r' % value) def ConvertToMSBuild(self, value): @@ -122,11 +122,11 @@ class _StringList(_Type): """A settings that's a list of strings.""" def ValidateMSVS(self, value): - if not isinstance(value, basestring) and not isinstance(value, list): + if not isinstance(value, str) and not isinstance(value, list): raise ValueError('expected string list; got %r' % value) def ValidateMSBuild(self, value): - if not isinstance(value, basestring) and not isinstance(value, list): + if not isinstance(value, str) and not isinstance(value, list): raise ValueError('expected string list; got %r' % value) def ConvertToMSBuild(self, value): @@ -191,8 +191,8 @@ class _Enumeration(_Type): def __init__(self, label_list, new=None): _Type.__init__(self) self._label_list = label_list - self._msbuild_values = set(value for value in label_list - if value is not None) + self._msbuild_values = {value for value in label_list + if value is not None} if new is not None: self._msbuild_values.update(new) @@ -337,7 +337,7 @@ def _ConvertedToAdditionalOption(tool, msvs_name, flag): if value == 'true': tool_settings = _GetMSBuildToolSettings(msbuild_settings, tool) if 'AdditionalOptions' in tool_settings: - new_flags = '%s %s' % (tool_settings['AdditionalOptions'], flag) + new_flags = '{} {}'.format(tool_settings['AdditionalOptions'], flag) else: new_flags = flag tool_settings['AdditionalOptions'] = new_flags @@ -400,7 +400,7 @@ def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr): if unrecognized: # We don't know this setting. Give a warning. - print >> stderr, error_msg + print(error_msg, file=stderr) def FixVCMacroSlashes(s): @@ -433,7 +433,7 @@ def ConvertVCMacrosToMSBuild(s): '$(PlatformName)': '$(Platform)', '$(SafeInputName)': '%(Filename)', } - for old, new in replace_map.iteritems(): + for old, new in replace_map.items(): s = s.replace(old, new) s = FixVCMacroSlashes(s) return s @@ -453,17 +453,17 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): dictionaries of settings and their values. """ msbuild_settings = {} - for msvs_tool_name, msvs_tool_settings in msvs_settings.iteritems(): + for msvs_tool_name, msvs_tool_settings in msvs_settings.items(): if msvs_tool_name in _msvs_to_msbuild_converters: msvs_tool = _msvs_to_msbuild_converters[msvs_tool_name] - for msvs_setting, msvs_value in msvs_tool_settings.iteritems(): + for msvs_setting, msvs_value in msvs_tool_settings.items(): if msvs_setting in msvs_tool: # Invoke the translation function. try: msvs_tool[msvs_setting](msvs_value, msbuild_settings) - except ValueError, e: - print >> stderr, ('Warning: while converting %s/%s to MSBuild, ' - '%s' % (msvs_tool_name, msvs_setting, e)) + except ValueError as e: + print(('Warning: while converting %s/%s to MSBuild, ' + '%s' % (msvs_tool_name, msvs_setting, e)), file=stderr) else: _ValidateExclusionSetting(msvs_setting, msvs_tool, @@ -472,8 +472,8 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): (msvs_tool_name, msvs_setting)), stderr) else: - print >> stderr, ('Warning: unrecognized tool %s while converting to ' - 'MSBuild.' % msvs_tool_name) + print(('Warning: unrecognized tool %s while converting to ' + 'MSBuild.' % msvs_tool_name), file=stderr) return msbuild_settings @@ -513,13 +513,13 @@ def _ValidateSettings(validators, settings, stderr): for tool_name in settings: if tool_name in validators: tool_validators = validators[tool_name] - for setting, value in settings[tool_name].iteritems(): + for setting, value in settings[tool_name].items(): if setting in tool_validators: try: tool_validators[setting](value) - except ValueError, e: - print >> stderr, ('Warning: for %s/%s, %s' % - (tool_name, setting, e)) + except ValueError as e: + print(('Warning: for %s/%s, %s' % + (tool_name, setting, e)), file=stderr) else: _ValidateExclusionSetting(setting, tool_validators, @@ -528,7 +528,7 @@ def _ValidateSettings(validators, settings, stderr): stderr) else: - print >> stderr, ('Warning: unrecognized tool %s' % tool_name) + print(('Warning: unrecognized tool %s' % tool_name), file=stderr) # MSVS and MBuild names of the tools. diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSToolFile.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSToolFile.py index 74e529a17f..ef5b12231f 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSToolFile.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSToolFile.py @@ -8,7 +8,7 @@ import gyp.common import gyp.easy_xml as easy_xml -class Writer(object): +class Writer: """Visual Studio XML tool file writer.""" def __init__(self, tool_file_path, name): diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py index 6c07e9a893..6dda1e1b03 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py @@ -51,7 +51,7 @@ def _QuoteWin32CommandLineArgs(args): new_args.append(arg) return new_args -class Writer(object): +class Writer: """Visual Studio XML user user file writer.""" def __init__(self, user_file_path, version, name): @@ -90,8 +90,8 @@ class Writer(object): abs_command = _FindCommandInPath(command[0]) if environment and isinstance(environment, dict): - env_list = ['%s="%s"' % (key, val) - for (key,val) in environment.iteritems()] + env_list = ['{}="{}"'.format(key, val) + for (key,val) in environment.items()] environment = ' '.join(env_list) else: environment = '' @@ -135,7 +135,7 @@ class Writer(object): def WriteIfChanged(self): """Writes the user file.""" configs = ['Configurations'] - for config, spec in sorted(self.configurations.iteritems()): + for config, spec in sorted(self.configurations.items()): configs.append(spec) content = ['VisualStudioUserFile', diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUtil.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUtil.py index 96dea6c2c9..28b725d00c 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUtil.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUtil.py @@ -55,7 +55,7 @@ def _SuffixName(name, suffix): Target name with suffix added (foo_suffix#target) """ parts = name.rsplit('#', 1) - parts[0] = '%s_%s' % (parts[0], suffix) + parts[0] = '{}_{}'.format(parts[0], suffix) return '#'.join(parts) @@ -160,7 +160,7 @@ def _GetPdbPath(target_dict, config_name, vars): pdb_base = target_dict.get('product_name', target_dict['target_name']) - pdb_base = '%s.%s.pdb' % (pdb_base, TARGET_TYPE_EXT[target_dict['type']]) + pdb_base = '{}.{}.pdb'.format(pdb_base, TARGET_TYPE_EXT[target_dict['type']]) pdb_path = vars['PRODUCT_DIR'] + '/' + pdb_base return pdb_path @@ -236,7 +236,7 @@ def InsertLargePdbShims(target_list, target_dicts, vars): # Set up the shim to output its PDB to the same location as the final linker # target. - for config_name, config in shim_dict.get('configurations').iteritems(): + for config_name, config in shim_dict.get('configurations').items(): pdb_path = _GetPdbPath(target_dict, config_name, vars) # A few keys that we don't want to propagate. diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSVersion.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSVersion.py index edaf6eed00..6ff461102f 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSVersion.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSVersion.py @@ -13,7 +13,7 @@ import gyp import glob -class VisualStudioVersion(object): +class VisualStudioVersion: """Information regarding a version of Visual Studio.""" def __init__(self, short_name, description, @@ -168,7 +168,7 @@ def _RegistryQuery(key, value=None): text = None try: text = _RegistryQueryBase('Sysnative', key, value) - except OSError, e: + except OSError as e: if e.errno == errno.ENOENT: text = _RegistryQueryBase('System32', key, value) else: @@ -186,13 +186,13 @@ def _RegistryGetValueUsingWinReg(key, value): contents of the registry key's value, or None on failure. Throws ImportError if _winreg is unavailable. """ - import _winreg + import six.moves.winreg try: root, subkey = key.split('\\', 1) assert root == 'HKLM' # Only need HKLM for now. - with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: - return _winreg.QueryValueEx(hkey, value)[0] - except WindowsError: + with six.moves.winreg.OpenKey(six.moves.winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: + return six.moves.winreg.QueryValueEx(hkey, value)[0] + except OSError: return None diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/__init__.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/__init__.py index b26977592b..6871786a60 100755 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/__init__.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/__init__.py @@ -34,8 +34,8 @@ def DebugOutput(mode, message, *args): pass if args: message %= args - print '%s:%s:%d:%s %s' % (mode.upper(), os.path.basename(ctx[0]), - ctx[1], ctx[2], message) + print('%s:%s:%d:%s %s' % (mode.upper(), os.path.basename(ctx[0]), + ctx[1], ctx[2], message)) def FindBuildFiles(): extension = '.gyp' @@ -163,7 +163,7 @@ def ShlexEnv(env_name): def FormatOpt(opt, value): if opt.startswith('--'): - return '%s=%s' % (opt, value) + return '{}={}'.format(opt, value) return opt + value def RegenerateAppendFlag(flag, values, predicate, env_name, options): @@ -210,7 +210,7 @@ def RegenerateFlags(options): # We always want to ignore the environment when regenerating, to avoid # duplicate or changed flags in the environment at the time of regeneration. flags = ['--ignore-environment'] - for name, metadata in options._regeneration_metadata.iteritems(): + for name, metadata in options._regeneration_metadata.items(): opt = metadata['opt'] value = getattr(options, name) value_predicate = metadata['type'] == 'path' and FixPath or Noop @@ -229,12 +229,12 @@ def RegenerateFlags(options): (action == 'store_false' and not value)): flags.append(opt) elif options.use_environment and env_name: - print >>sys.stderr, ('Warning: environment regeneration unimplemented ' + print(('Warning: environment regeneration unimplemented ' 'for %s flag %r env_name %r' % (action, opt, - env_name)) + env_name)), file=sys.stderr) else: - print >>sys.stderr, ('Warning: regeneration unimplemented for action %r ' - 'flag %r' % (action, opt)) + print(('Warning: regeneration unimplemented for action %r ' + 'flag %r' % (action, opt)), file=sys.stderr) return flags @@ -413,7 +413,7 @@ def gyp_main(args): for option, value in sorted(options.__dict__.items()): if option[0] == '_': continue - if isinstance(value, basestring): + if isinstance(value, str): DebugOutput(DEBUG_GENERAL, " %s: '%s'", option, value) else: DebugOutput(DEBUG_GENERAL, " %s: %s", option, value) @@ -435,7 +435,7 @@ def gyp_main(args): build_file_dir = os.path.abspath(os.path.dirname(build_file)) build_file_dir_components = build_file_dir.split(os.path.sep) components_len = len(build_file_dir_components) - for index in xrange(components_len - 1, -1, -1): + for index in range(components_len - 1, -1, -1): if build_file_dir_components[index] == 'src': options.depth = os.path.sep.join(build_file_dir_components) break @@ -478,7 +478,7 @@ def gyp_main(args): if home_dot_gyp != None: default_include = os.path.join(home_dot_gyp, 'include.gypi') if os.path.exists(default_include): - print 'Using overrides found in ' + default_include + print('Using overrides found in ' + default_include) includes.append(default_include) # Command-line --include files come after the default include. @@ -493,7 +493,7 @@ def gyp_main(args): if options.generator_flags: gen_flags += options.generator_flags generator_flags = NameValueListToDict(gen_flags) - if DEBUG_GENERAL in gyp.debug.keys(): + if DEBUG_GENERAL in list(gyp.debug.keys()): DebugOutput(DEBUG_GENERAL, "generator_flags: %s", generator_flags) # Generate all requested formats (use a set in case we got one format request @@ -526,7 +526,7 @@ def gyp_main(args): generator.GenerateOutput(flat_list, targets, data, params) if options.configs: - valid_configs = targets[flat_list[0]]['configurations'].keys() + valid_configs = list(targets[flat_list[0]]['configurations'].keys()) for conf in options.configs: if conf not in valid_configs: raise GypError('Invalid config specified via --build: %s' % conf) @@ -539,7 +539,7 @@ def gyp_main(args): def main(args): try: return gyp_main(args) - except GypError, e: + except GypError as e: sys.stderr.write("gyp: %s\n" % e) return 1 diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py index a1e1db5f12..63effe882e 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py @@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -from __future__ import with_statement import collections import errno @@ -15,7 +14,7 @@ import sys # A minimal memoizing decorator. It'll blow up if the args aren't immutable, # among other "problems". -class memoize(object): +class memoize: def __init__(self, func): self.func = func self.cache = {} @@ -336,7 +335,7 @@ def WriteOnDiff(filename): the target if it differs (on close). """ - class Writer(object): + class Writer: """Wrapper around file which only covers the target if it differs.""" def __init__(self): # Pick temporary file. @@ -363,7 +362,7 @@ def WriteOnDiff(filename): same = False try: same = filecmp.cmp(self.tmp_path, filename, False) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: raise @@ -382,9 +381,9 @@ def WriteOnDiff(filename): # # No way to get the umask without setting a new one? Set a safe one # and then set it back to the old value. - umask = os.umask(077) + umask = os.umask(0o77) os.umask(umask) - os.chmod(self.tmp_path, 0666 & ~umask) + os.chmod(self.tmp_path, 0o666 & ~umask) if sys.platform == 'win32' and os.path.exists(filename): # NOTE: on windows (but not cygwin) rename will not replace an # existing file, so it must be preceded with a remove. Sadly there @@ -467,7 +466,7 @@ def CopyTool(flavor, out_path, generator_flags={}): ''.join([source[0], header] + source[1:])) # Make file executable. - os.chmod(tool_path, 0755) + os.chmod(tool_path, 0o755) # From Alex Martelli, @@ -490,7 +489,7 @@ def uniquer(seq, idfun=None): # Based on http://code.activestate.com/recipes/576694/. -class OrderedSet(collections.MutableSet): +class OrderedSet(collections.abc.MutableSet): def __init__(self, iterable=None): self.end = end = [] end += [None, end, end] # sentinel node for doubly linked list @@ -540,8 +539,8 @@ class OrderedSet(collections.MutableSet): def __repr__(self): if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, list(self)) + return '{}()'.format(self.__class__.__name__) + return '{}({!r})'.format(self.__class__.__name__, list(self)) def __eq__(self, other): if isinstance(other, OrderedSet): @@ -580,7 +579,7 @@ def TopologicallySorted(graph, get_edges): graph = {'a': '$(b) $(c)', 'b': 'hi', 'c': '$(b)'} def GetEdges(node): return re.findall(r'\$\(([^))]\)', graph[node]) - print TopologicallySorted(graph.keys(), GetEdges) + print(TopologicallySorted(graph.keys(), GetEdges)) ==> ['a', 'c', b'] """ diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/common_test.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/common_test.py index ad6f9a1438..a009f32389 100755 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/common_test.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/common_test.py @@ -23,7 +23,7 @@ class TestTopologicallySorted(unittest.TestCase): def GetEdge(node): return tuple(graph[node]) self.assertEqual( - gyp.common.TopologicallySorted(graph.keys(), GetEdge), + gyp.common.TopologicallySorted(list(graph.keys()), GetEdge), ['a', 'c', 'd', 'b']) def test_Cycle(self): @@ -38,7 +38,7 @@ class TestTopologicallySorted(unittest.TestCase): return tuple(graph[node]) self.assertRaises( gyp.common.CycleError, gyp.common.TopologicallySorted, - graph.keys(), GetEdge) + list(graph.keys()), GetEdge) class TestGetFlavor(unittest.TestCase): diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/easy_xml.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/easy_xml.py index bf949b6ac9..6f396f6b9f 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/easy_xml.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/easy_xml.py @@ -4,6 +4,7 @@ import re import os +from functools import reduce def XmlToString(content, encoding='utf-8', pretty=False): @@ -79,8 +80,8 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0): # Optionally in second position is a dictionary of the attributes. rest = specification[1:] if rest and isinstance(rest[0], dict): - for at, val in sorted(rest[0].iteritems()): - xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True))) + for at, val in sorted(rest[0].items()): + xml_parts.append(' {}="{}"'.format(at, _XmlEscape(val, attr=True))) rest = rest[1:] if rest: xml_parts.append('>') @@ -97,7 +98,7 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0): _ConstructContentList(xml_parts, child_spec, pretty, level + 1) if multi_line and indentation: xml_parts.append(indentation) - xml_parts.append('%s' % (name, new_line)) + xml_parts.append('{}'.format(name, new_line)) else: xml_parts.append('/>%s' % new_line) @@ -118,7 +119,7 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, # Get the old content try: - f = open(path, 'r') + f = open(path) existing = f.read() f.close() except: @@ -143,7 +144,7 @@ _xml_escape_map = { _xml_escape_re = re.compile( - "(%s)" % "|".join(map(re.escape, _xml_escape_map.keys()))) + "(%s)" % "|".join(map(re.escape, list(_xml_escape_map.keys())))) def _XmlEscape(value, attr=False): diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/flock_tool.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/flock_tool.py index b38d8660f7..0cccb49c69 100755 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/flock_tool.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/flock_tool.py @@ -18,7 +18,7 @@ def main(args): executor.Dispatch(args) -class FlockTool(object): +class FlockTool: """This class emulates the 'flock' command.""" def Dispatch(self, args): """Dispatches a string command to a method.""" @@ -39,7 +39,7 @@ class FlockTool(object): # where fcntl.flock(fd, LOCK_EX) always fails # with EBADF, that's why we use this F_SETLK # hack instead. - fd = os.open(lockfile, os.O_WRONLY|os.O_NOCTTY|os.O_CREAT, 0666) + fd = os.open(lockfile, os.O_WRONLY|os.O_NOCTTY|os.O_CREAT, 0o666) if sys.platform.startswith('aix'): # Python on AIX is compiled with LARGEFILE support, which changes the # struct size. diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/analyzer.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/analyzer.py index 921c1a6b71..5922b9a834 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/analyzer.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/analyzer.py @@ -68,6 +68,7 @@ import json import os import posixpath import sys +import six debug = False @@ -155,7 +156,7 @@ def _AddSources(sources, base_path, base_path_components, result): continue result.append(base_path + source) if debug: - print 'AddSource', org_source, result[len(result) - 1] + print('AddSource', org_source, result[len(result) - 1]) def _ExtractSourcesFromAction(action, base_path, base_path_components, @@ -185,7 +186,7 @@ def _ExtractSources(target, target_dict, toplevel_dir): base_path += '/' if debug: - print 'ExtractSources', target, base_path + print('ExtractSources', target, base_path) results = [] if 'sources' in target_dict: @@ -204,7 +205,7 @@ def _ExtractSources(target, target_dict, toplevel_dir): return results -class Target(object): +class Target: """Holds information about a particular target: deps: set of Targets this Target depends upon. This is not recursive, only the direct dependent Targets. @@ -239,7 +240,7 @@ class Target(object): self.is_or_has_linked_ancestor = False -class Config(object): +class Config: """Details what we're looking for files: set of files to search for targets: see file description for details.""" @@ -257,10 +258,10 @@ class Config(object): if not config_path: return try: - f = open(config_path, 'r') + f = open(config_path) config = json.load(f) f.close() - except IOError: + except OSError: raise Exception('Unable to open file ' + config_path) except ValueError as e: raise Exception('Unable to parse config file ' + config_path + str(e)) @@ -278,7 +279,7 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir): the root of the source tree.""" if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files: if debug: - print 'gyp file modified', build_file + print('gyp file modified', build_file) return True # First element of included_files is the file itself. @@ -291,8 +292,8 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir): _ToGypPath(gyp.common.UnrelativePath(include_file, build_file)) if _ToLocalPath(toplevel_dir, rel_include_file) in files: if debug: - print 'included gyp file modified, gyp_file=', build_file, \ - 'included file=', rel_include_file + print('included gyp file modified, gyp_file=', build_file, \ + 'included file=', rel_include_file) return True return False @@ -373,7 +374,7 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, # If a build file (or any of its included files) is modified we assume all # targets in the file are modified. if build_file_in_files[build_file]: - print 'matching target from modified build file', target_name + print('matching target from modified build file', target_name) target.match_status = MATCH_STATUS_MATCHES matching_targets.append(target) else: @@ -381,7 +382,7 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, toplevel_dir) for source in sources: if _ToGypPath(os.path.normpath(source)) in files: - print 'target', target_name, 'matches', source + print('target', target_name, 'matches', source) target.match_status = MATCH_STATUS_MATCHES matching_targets.append(target) break @@ -433,7 +434,7 @@ def _DoesTargetDependOnMatchingTargets(target): for dep in target.deps: if _DoesTargetDependOnMatchingTargets(dep): target.match_status = MATCH_STATUS_MATCHES_BY_DEPENDENCY - print '\t', target.name, 'matches by dep', dep.name + print('\t', target.name, 'matches by dep', dep.name) return True target.match_status = MATCH_STATUS_DOESNT_MATCH return False @@ -445,7 +446,7 @@ def _GetTargetsDependingOnMatchingTargets(possible_targets): supplied as input to analyzer. possible_targets: targets to search from.""" found = [] - print 'Targets that matched by dependency:' + print('Targets that matched by dependency:') for target in possible_targets: if _DoesTargetDependOnMatchingTargets(target): found.append(target) @@ -484,12 +485,12 @@ def _AddCompileTargets(target, roots, add_if_no_ancestor, result): (add_if_no_ancestor or target.requires_build)) or (target.is_static_library and add_if_no_ancestor and not target.is_or_has_linked_ancestor)): - print '\t\tadding to compile targets', target.name, 'executable', \ + print('\t\tadding to compile targets', target.name, 'executable', \ target.is_executable, 'added_to_compile_targets', \ target.added_to_compile_targets, 'add_if_no_ancestor', \ add_if_no_ancestor, 'requires_build', target.requires_build, \ 'is_static_library', target.is_static_library, \ - 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor + 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor) result.add(target) target.added_to_compile_targets = True @@ -500,7 +501,7 @@ def _GetCompileTargets(matching_targets, supplied_targets): supplied_targets: set of targets supplied to analyzer to search from.""" result = set() for target in matching_targets: - print 'finding compile targets for match', target.name + print('finding compile targets for match', target.name) _AddCompileTargets(target, supplied_targets, True, result) return result @@ -508,46 +509,46 @@ def _GetCompileTargets(matching_targets, supplied_targets): def _WriteOutput(params, **values): """Writes the output, either to stdout or a file is specified.""" if 'error' in values: - print 'Error:', values['error'] + print('Error:', values['error']) if 'status' in values: - print values['status'] + print(values['status']) if 'targets' in values: values['targets'].sort() - print 'Supplied targets that depend on changed files:' + print('Supplied targets that depend on changed files:') for target in values['targets']: - print '\t', target + print('\t', target) if 'invalid_targets' in values: values['invalid_targets'].sort() - print 'The following targets were not found:' + print('The following targets were not found:') for target in values['invalid_targets']: - print '\t', target + print('\t', target) if 'build_targets' in values: values['build_targets'].sort() - print 'Targets that require a build:' + print('Targets that require a build:') for target in values['build_targets']: - print '\t', target + print('\t', target) if 'compile_targets' in values: values['compile_targets'].sort() - print 'Targets that need to be built:' + print('Targets that need to be built:') for target in values['compile_targets']: - print '\t', target + print('\t', target) if 'test_targets' in values: values['test_targets'].sort() - print 'Test targets:' + print('Test targets:') for target in values['test_targets']: - print '\t', target + print('\t', target) output_path = params.get('generator_flags', {}).get( 'analyzer_output_path', None) if not output_path: - print json.dumps(values) + print(json.dumps(values)) return try: f = open(output_path, 'w') f.write(json.dumps(values) + '\n') f.close() - except IOError as e: - print 'Error writing to output file', output_path, str(e) + except OSError as e: + print('Error writing to output file', output_path, str(e)) def _WasGypIncludeFileModified(params, files): @@ -556,7 +557,7 @@ def _WasGypIncludeFileModified(params, files): if params['options'].includes: for include in params['options'].includes: if _ToGypPath(os.path.normpath(include)) in files: - print 'Include file modified, assuming all changed', include + print('Include file modified, assuming all changed', include) return True return False @@ -595,7 +596,7 @@ def CalculateVariables(default_variables, params): default_variables.setdefault('OS', operating_system) -class TargetCalculator(object): +class TargetCalculator: """Calculates the matching test_targets and matching compile_targets.""" def __init__(self, files, additional_compile_target_names, test_target_names, data, target_list, target_dicts, toplevel_dir, build_files): @@ -638,13 +639,13 @@ class TargetCalculator(object): set(self._root_targets))] else: test_targets = [x for x in test_targets_no_all] - print 'supplied test_targets' + print('supplied test_targets') for target_name in self._test_target_names: - print '\t', target_name - print 'found test_targets' + print('\t', target_name) + print('found test_targets') for target in test_targets: - print '\t', target.name - print 'searching for matching test targets' + print('\t', target.name) + print('searching for matching test targets') matching_test_targets = _GetTargetsDependingOnMatchingTargets(test_targets) matching_test_targets_contains_all = (test_target_names_contains_all and set(matching_test_targets) & @@ -654,14 +655,14 @@ class TargetCalculator(object): # 'all' is subsequentely added to the matching names below. matching_test_targets = [x for x in (set(matching_test_targets) & set(test_targets_no_all))] - print 'matched test_targets' + print('matched test_targets') for target in matching_test_targets: - print '\t', target.name + print('\t', target.name) matching_target_names = [gyp.common.ParseQualifiedTarget(target.name)[1] for target in matching_test_targets] if matching_test_targets_contains_all: matching_target_names.append('all') - print '\tall' + print('\tall') return matching_target_names def find_matching_compile_target_names(self): @@ -669,7 +670,7 @@ class TargetCalculator(object): assert self.is_build_impacted(); # Compile targets are found by searching up from changed targets. # Reset the visited status for _GetBuildTargets. - for target in self._name_to_target.itervalues(): + for target in self._name_to_target.values(): target.visited = False supplied_targets = _LookupTargets(self._supplied_target_names_no_all(), @@ -677,10 +678,10 @@ class TargetCalculator(object): if 'all' in self._supplied_target_names(): supplied_targets = [x for x in (set(supplied_targets) | set(self._root_targets))] - print 'Supplied test_targets & compile_targets' + print('Supplied test_targets & compile_targets') for target in supplied_targets: - print '\t', target.name - print 'Finding compile targets' + print('\t', target.name) + print('Finding compile targets') compile_targets = _GetCompileTargets(self._changed_targets, supplied_targets) return [gyp.common.ParseQualifiedTarget(target.name)[1] @@ -699,7 +700,7 @@ def GenerateOutput(target_list, target_dicts, data, params): toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir)) if debug: - print 'toplevel_dir', toplevel_dir + print('toplevel_dir', toplevel_dir) if _WasGypIncludeFileModified(params, config.files): result_dict = { 'status': all_changed_string, diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/cmake.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/cmake.py index a2b96291aa..351a30da70 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/cmake.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/cmake.py @@ -214,7 +214,7 @@ def WriteVariable(output, variable_name, prepend=None): output.write('}') -class CMakeTargetType(object): +class CMakeTargetType: def __init__(self, command, modifier, property_modifier): self.command = command self.modifier = modifier @@ -255,7 +255,7 @@ def WriteActions(target_name, actions, extra_sources, extra_deps, """ for action in actions: action_name = StringToCMakeTargetName(action['action_name']) - action_target_name = '%s__%s' % (target_name, action_name) + action_target_name = '{}__{}'.format(target_name, action_name) inputs = action['inputs'] inputs_name = action_target_name + '__input' @@ -270,10 +270,10 @@ def WriteActions(target_name, actions, extra_sources, extra_deps, # Build up a list of outputs. # Collect the output dirs we'll need. - dirs = set(dir for dir in (os.path.dirname(o) for o in outputs) if dir) + dirs = {dir for dir in (os.path.dirname(o) for o in outputs) if dir} if int(action.get('process_outputs_as_sources', False)): - extra_sources.extend(zip(cmake_outputs, outputs)) + extra_sources.extend(list(zip(cmake_outputs, outputs))) # add_custom_command output.write('add_custom_command(OUTPUT ') @@ -363,7 +363,7 @@ def WriteRules(target_name, rules, extra_sources, extra_deps, # Build up a list of outputs. # Collect the output dirs we'll need. - dirs = set(dir for dir in (os.path.dirname(o) for o in outputs) if dir) + dirs = {dir for dir in (os.path.dirname(o) for o in outputs) if dir} # Create variables for the output, as 'local' variable will be unset. these_outputs = [] @@ -462,7 +462,7 @@ def WriteCopies(target_name, copies, extra_deps, path_to_gyp, output): extra_deps.append(copy_name) return - class Copy(object): + class Copy: def __init__(self, ext, command): self.cmake_inputs = [] self.cmake_outputs = [] @@ -569,7 +569,7 @@ def CreateCMakeTargetFullName(qualified_target): return StringToCMakeTargetName(cmake_target_full_name) -class CMakeNamer(object): +class CMakeNamer: """Converts Gyp target names into CMake target names. CMake requires that target names be globally unique. One way to ensure @@ -644,7 +644,7 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type) if cmake_target_type is None: - print ('Target %s has unknown target type %s, skipping.' % + print('Target %s has unknown target type %s, skipping.' % ( target_name, target_type ) ) return @@ -868,8 +868,8 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, default_product_ext = generator_default_variables['SHARED_LIB_SUFFIX'] elif target_type != 'executable': - print ('ERROR: What output file should be generated?', - 'type', target_type, 'target', target_name) + print(('ERROR: What output file should be generated?', + 'type', target_type, 'target', target_name)) product_prefix = spec.get('product_prefix', default_product_prefix) product_name = spec.get('product_name', default_product_name) @@ -979,7 +979,7 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, # XCode settings xcode_settings = config.get('xcode_settings', {}) - for xcode_setting, xcode_value in xcode_settings.viewitems(): + for xcode_setting, xcode_value in xcode_settings.items(): SetTargetProperty(output, cmake_target_name, "XCODE_ATTRIBUTE_%s" % xcode_setting, xcode_value, '' if isinstance(xcode_value, str) else ' ') @@ -1207,11 +1207,11 @@ def PerformBuild(data, configurations, params): output_dir, config_name)) arguments = ['cmake', '-G', 'Ninja'] - print 'Generating [%s]: %s' % (config_name, arguments) + print('Generating [{}]: {}'.format(config_name, arguments)) subprocess.check_call(arguments, cwd=build_dir) arguments = ['ninja', '-C', build_dir] - print 'Building [%s]: %s' % (config_name, arguments) + print('Building [{}]: {}'.format(config_name, arguments)) subprocess.check_call(arguments) @@ -1230,7 +1230,7 @@ def GenerateOutput(target_list, target_dicts, data, params): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: - config_names = target_dicts[target_list[0]]['configurations'].keys() + config_names = list(target_dicts[target_list[0]]['configurations'].keys()) if params['parallel']: try: pool = multiprocessing.Pool(len(config_names)) @@ -1239,7 +1239,7 @@ def GenerateOutput(target_list, target_dicts, data, params): arglists.append((target_list, target_dicts, data, params, config_name)) pool.map(CallGenerateOutputForConfig, arglists) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: pool.terminate() raise e else: diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/dump_dependency_json.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/dump_dependency_json.py index 160eafe2ef..719b6c1e54 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/dump_dependency_json.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/dump_dependency_json.py @@ -96,4 +96,4 @@ def GenerateOutput(target_list, target_dicts, data, params): f = open(filename, 'w') json.dump(edges, f) f.close() - print 'Wrote json to %s.' % filename + print('Wrote json to %s.' % filename) diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/eclipse.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/eclipse.py index 3544347b3b..a226c19fc5 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/eclipse.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/eclipse.py @@ -24,7 +24,7 @@ import gyp import gyp.common import gyp.msvs_emulation import shlex -import xml.etree.cElementTree as ET +import xml.etree.ElementTree as ET generator_wants_static_library_dependencies_adjusted = False @@ -141,7 +141,7 @@ def GetAllIncludeDirectories(target_list, target_dicts, compiler_includes_list.append(include_dir) # Find standard gyp include dirs. - if config.has_key('include_dirs'): + if 'include_dirs' in config: include_dirs = config['include_dirs'] for shared_intermediate_dir in shared_intermediate_dirs: for include_dir in include_dirs: @@ -272,7 +272,7 @@ def WriteMacros(out, eclipse_langs, defines): out.write(' \n') for lang in eclipse_langs: out.write(' \n' % lang) - for key in sorted(defines.iterkeys()): + for key in sorted(defines.keys()): out.write(' %s%s\n' % (escape(key), escape(defines[key]))) out.write(' \n') @@ -418,7 +418,7 @@ def GenerateOutput(target_list, target_dicts, data, params): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: - config_names = target_dicts[target_list[0]]['configurations'].keys() + config_names = list(target_dicts[target_list[0]]['configurations'].keys()) for config_name in config_names: GenerateOutputForConfig(target_list, target_dicts, data, params, config_name) diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/gypd.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/gypd.py index 3efdb9966a..78eeaa61b2 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/gypd.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/gypd.py @@ -88,7 +88,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if not output_file in output_files: output_files[output_file] = input_file - for output_file, input_file in output_files.iteritems(): + for output_file, input_file in output_files.items(): output = open(output_file, 'w') pprint.pprint(data[input_file], output) output.close() diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/make.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/make.py index b7da768fb3..3339cf6b0f 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/make.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/make.py @@ -499,7 +499,7 @@ cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) def WriteRootHeaderSuffixRules(writer): - extensions = sorted(COMPILABLE_EXTENSIONS.keys(), key=str.lower) + extensions = sorted(list(COMPILABLE_EXTENSIONS.keys()), key=str.lower) writer.write('# Suffix rules, putting all outputs into $(obj).\n') for ext in extensions: @@ -645,9 +645,9 @@ def _ValidateSourcesForOSX(spec, all_sources): basenames.setdefault(basename, []).append(source) error = '' - for basename, files in basenames.iteritems(): + for basename, files in basenames.items(): if len(files) > 1: - error += ' %s: %s\n' % (basename, ' '.join(files)) + error += ' {}: {}\n'.format(basename, ' '.join(files)) if error: print('static library %s has several files with the same basename:\n' % @@ -665,7 +665,7 @@ target_outputs = {} target_link_deps = {} -class MakefileWriter(object): +class MakefileWriter: """MakefileWriter packages up the writing of one target-specific foobar.mk. Its only real entry point is Write(), and is mostly used for namespacing. @@ -683,19 +683,19 @@ class MakefileWriter(object): for ext in COMPILABLE_EXTENSIONS.keys(): # Suffix rules for source folder. self.suffix_rules_srcdir.update({ext: ("""\ -$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD - @$(call do_cmd,%s,1) -""" % (ext, COMPILABLE_EXTENSIONS[ext]))}) +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%{} FORCE_DO_CMD + @$(call do_cmd,{},1) +""".format(ext, COMPILABLE_EXTENSIONS[ext]))}) # Suffix rules for generated source files. self.suffix_rules_objdir1.update({ext: ("""\ -$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD - @$(call do_cmd,%s,1) -""" % (ext, COMPILABLE_EXTENSIONS[ext]))}) +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%{} FORCE_DO_CMD + @$(call do_cmd,{},1) +""".format(ext, COMPILABLE_EXTENSIONS[ext]))}) self.suffix_rules_objdir2.update({ext: ("""\ -$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD - @$(call do_cmd,%s,1) -""" % (ext, COMPILABLE_EXTENSIONS[ext]))}) +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%{} FORCE_DO_CMD + @$(call do_cmd,{},1) +""".format(ext, COMPILABLE_EXTENSIONS[ext]))}) def Write(self, qualified_target, base_path, output_filename, spec, configs, @@ -793,10 +793,10 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD gyp.xcode_emulation.MacPrefixHeader( self.xcode_settings, lambda p: Sourceify(self.Absolutify(p)), self.Pchify)) - sources = filter(Compilable, all_sources) + sources = list(filter(Compilable, all_sources)) if sources: self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT1) - extensions = set([os.path.splitext(s)[1] for s in sources]) + extensions = {os.path.splitext(s)[1] for s in sources} for ext in extensions: if ext in self.suffix_rules_srcdir: self.WriteLn(self.suffix_rules_srcdir[ext]) @@ -854,7 +854,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD self.WriteLn('all:') if makefile_path: makefile_path = ' -C ' + makefile_path - self.WriteLn('\t$(MAKE)%s %s' % (makefile_path, ' '.join(targets))) + self.WriteLn('\t$(MAKE){} {}'.format(makefile_path, ' '.join(targets))) self.fp.close() @@ -871,7 +871,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD """ env = self.GetSortedXcodeEnv() for action in actions: - name = StringToMakefileVariable('%s_%s' % (self.qualified_target, + name = StringToMakefileVariable('{}_{}'.format(self.qualified_target, action['action_name'])) self.WriteLn('### Rules for action "%s":' % action['action_name']) inputs = action['inputs'] @@ -896,9 +896,9 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD for command in action_commands] command = gyp.common.EncodePOSIXShellList(action_commands) if 'message' in action: - self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, action['message'])) + self.WriteLn('quiet_cmd_{} = ACTION {} $@'.format(name, action['message'])) else: - self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, name)) + self.WriteLn('quiet_cmd_{} = ACTION {} $@'.format(name, name)) if len(dirs) > 0: command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command @@ -922,7 +922,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD '%s%s' % (name, cd_action, command)) self.WriteLn() - outputs = map(self.Absolutify, outputs) + outputs = list(map(self.Absolutify, outputs)) # The makefile rules are all relative to the top dir, but the gyp actions # are defined relative to their containing dir. This replaces the obj # variable for the action rule with an absolute version so that the output @@ -946,12 +946,12 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs] inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs] - self.WriteDoCmd(outputs, map(Sourceify, map(self.Absolutify, inputs)), + self.WriteDoCmd(outputs, list(map(Sourceify, list(map(self.Absolutify, inputs)))), part_of_all=part_of_all, command=name) # Stuff the outputs in a variable so we can refer to them later. outputs_variable = 'action_%s_outputs' % name - self.WriteLn('%s := %s' % (outputs_variable, ' '.join(outputs))) + self.WriteLn('{} := {}'.format(outputs_variable, ' '.join(outputs))) extra_outputs.append('$(%s)' % outputs_variable) self.WriteLn() @@ -970,7 +970,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD """ env = self.GetSortedXcodeEnv() for rule in rules: - name = StringToMakefileVariable('%s_%s' % (self.qualified_target, + name = StringToMakefileVariable('{}_{}'.format(self.qualified_target, rule['rule_name'])) count = 0 self.WriteLn('### Generated for rule %s:' % name) @@ -995,8 +995,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD extra_sources += outputs if int(rule.get('process_outputs_as_mac_bundle_resources', False)): extra_mac_bundle_resources += outputs - inputs = map(Sourceify, map(self.Absolutify, [rule_source] + - rule.get('inputs', []))) + inputs = list(map(Sourceify, list(map(self.Absolutify, [rule_source] + + rule.get('inputs', []))))) actions = ['$(call do_cmd,%s_%d)' % (name, count)] if name == 'resources_grit': @@ -1012,7 +1012,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs] inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs] - outputs = map(self.Absolutify, outputs) + outputs = list(map(self.Absolutify, outputs)) all_outputs += outputs # Only write the 'obj' and 'builddir' rules for the "primary" output # (:1); it's superfluous for the "extra outputs", and this avoids @@ -1119,7 +1119,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD path = gyp.xcode_emulation.ExpandEnvVars(path, env) self.WriteDoCmd([output], [path], 'copy', part_of_all) outputs.append(output) - self.WriteLn('%s = %s' % (variable, ' '.join(map(QuoteSpaces, outputs)))) + self.WriteLn('{} = {}'.format(variable, ' '.join(map(QuoteSpaces, outputs)))) extra_outputs.append('$(%s)' % variable) self.WriteLn() @@ -1130,7 +1130,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD for output, res in gyp.xcode_emulation.GetMacBundleResources( generator_default_variables['PRODUCT_DIR'], self.xcode_settings, - map(Sourceify, map(self.Absolutify, resources))): + list(map(Sourceify, list(map(self.Absolutify, resources))))): _, ext = os.path.splitext(output) if ext != '.xcassets': # Make does not supports '.xcassets' emulation. @@ -1210,11 +1210,11 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD self.WriteList(cflags_objcc, 'CFLAGS_OBJCC_%s' % configname) includes = config.get('include_dirs') if includes: - includes = map(Sourceify, map(self.Absolutify, includes)) + includes = list(map(Sourceify, list(map(self.Absolutify, includes)))) self.WriteList(includes, 'INCS_%s' % configname, prefix='-I') - compilable = filter(Compilable, sources) - objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable))) + compilable = list(filter(Compilable, sources)) + objs = list(map(self.Objectify, list(map(self.Absolutify, list(map(Target, compilable)))))) self.WriteList(objs, 'OBJS') for obj in objs: @@ -1245,7 +1245,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD if pchdeps: self.WriteLn('# Dependencies from obj files to their precompiled headers') for source, obj, gch in pchdeps: - self.WriteLn('%s: %s' % (obj, gch)) + self.WriteLn('{}: {}'.format(obj, gch)) self.WriteLn('# End precompiled header dependencies') if objs: @@ -1286,7 +1286,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD # If there are any object files in our input file list, link them into our # output. - extra_link_deps += filter(Linkable, sources) + extra_link_deps += list(filter(Linkable, sources)) self.WriteLn() @@ -1308,13 +1308,13 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD 'm': 'GYP_PCH_OBJCFLAGS', 'mm': 'GYP_PCH_OBJCXXFLAGS', }[lang] - self.WriteLn("%s: %s := %s " % (gch, var_name, lang_flag) + + self.WriteLn("{}: {} := {} ".format(gch, var_name, lang_flag) + "$(DEFS_$(BUILDTYPE)) " "$(INCS_$(BUILDTYPE)) " "$(CFLAGS_$(BUILDTYPE)) " + extra_flags) - self.WriteLn('%s: %s FORCE_DO_CMD' % (gch, input)) + self.WriteLn('{}: {} FORCE_DO_CMD'.format(gch, input)) self.WriteLn('\t@$(call do_cmd,pch_%s,1)' % lang) self.WriteLn('') assert ' ' not in gch, ( @@ -1351,8 +1351,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD elif self.type == 'none': target = '%s.stamp' % target elif self.type != 'executable': - print ("ERROR: What output file should be generated?", - "type", self.type, "target", target) + print(("ERROR: What output file should be generated?", + "type", self.type, "target", target)) target_prefix = spec.get('product_prefix', target_prefix) target = spec.get('product_name', target) @@ -1516,11 +1516,11 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD # Postbuilds expect to be run in the gyp file's directory, so insert an # implicit postbuild to cd to there. postbuilds.insert(0, gyp.common.EncodePOSIXShellList(['cd', self.path])) - for i in xrange(len(postbuilds)): + for i in range(len(postbuilds)): if not postbuilds[i].startswith('$'): postbuilds[i] = EscapeShellArgument(postbuilds[i]) self.WriteLn('%s: builddir := $(abs_builddir)' % QuoteSpaces(self.output)) - self.WriteLn('%s: POSTBUILDS := %s' % ( + self.WriteLn('{}: POSTBUILDS := {}'.format( QuoteSpaces(self.output), ' '.join(postbuilds))) # A bundle directory depends on its dependencies such as bundle resources @@ -1533,7 +1533,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD # Bundle dependencies. Note that the code below adds actions to this # target, so if you move these two lines, move the lines below as well. - self.WriteList(map(QuoteSpaces, bundle_deps), 'BUNDLE_DEPS') + self.WriteList(list(map(QuoteSpaces, bundle_deps)), 'BUNDLE_DEPS') self.WriteLn('%s: $(BUNDLE_DEPS)' % QuoteSpaces(self.output)) # After the framework is built, package it. Needs to happen before @@ -1565,7 +1565,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD 'custom product_dir') if self.type == 'executable': - self.WriteLn('%s: LD_INPUTS := %s' % ( + self.WriteLn('{}: LD_INPUTS := {}'.format( QuoteSpaces(self.output_binary), ' '.join(map(QuoteSpaces, link_deps)))) if self.toolset == 'host' and self.flavor == 'android': @@ -1587,7 +1587,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD self.WriteDoCmd([self.output_binary], link_deps, 'alink', part_of_all, postbuilds=postbuilds) elif self.type == 'shared_library': - self.WriteLn('%s: LD_INPUTS := %s' % ( + self.WriteLn('{}: LD_INPUTS := {}'.format( QuoteSpaces(self.output_binary), ' '.join(map(QuoteSpaces, link_deps)))) self.WriteDoCmd([self.output_binary], link_deps, 'solink', part_of_all, @@ -1608,7 +1608,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all, postbuilds=postbuilds) else: - print "WARNING: no output for", self.type, target + print("WARNING: no output for", self.type, target) # Add an alias for each target (if there are any outputs). # Installable target aliases are created below. @@ -1638,7 +1638,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD if (self.flavor == 'mac' and not 'product_dir' in spec and self.toolset == 'target'): # On mac, products are created in install_path immediately. - assert install_path == self.output, '%s != %s' % ( + assert install_path == self.output, '{} != {}'.format( install_path, self.output) # Point the target alias to the final binary output. @@ -1672,7 +1672,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD if value_list: value_list = [quoter(prefix + l) for l in value_list] values = ' \\\n\t' + ' \\\n\t'.join(value_list) - self.fp.write('%s :=%s\n\n' % (variable, values)) + self.fp.write('{} :={}\n\n'.format(variable, values)) def WriteDoCmd(self, outputs, inputs, command, part_of_all, comment=None, @@ -1687,7 +1687,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD assert ',' not in command suffix = ',,1' # Tell do_cmd to honor $POSTBUILDS self.WriteMakeRule(outputs, inputs, - actions = ['$(call do_cmd,%s%s)' % (command, suffix)], + actions = ['$(call do_cmd,{}{})'.format(command, suffix)], comment = comment, command = command, force = True) @@ -1715,8 +1715,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD output is just a name to run the rule command: (optional) command name to generate unambiguous labels """ - outputs = map(QuoteSpaces, outputs) - inputs = map(QuoteSpaces, inputs) + outputs = list(map(QuoteSpaces, outputs)) + inputs = list(map(QuoteSpaces, inputs)) if comment: self.WriteLn('# ' + comment) @@ -1733,7 +1733,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD (' '.join(outputs), ' '.join(inputs), force_append)) elif len(outputs) == 1: # Regular rule, one output: Just write a simple rule. - self.WriteLn('%s: %s%s' % (outputs[0], ' '.join(inputs), force_append)) + self.WriteLn('{}: {}{}'.format(outputs[0], ' '.join(inputs), force_append)) else: # Regular rule, more than one output: Multiple outputs are tricky in # make. We will write three rules: @@ -1744,9 +1744,9 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD # - The intermediate recipe will 'touch' the intermediate file. # - The multi-output rule will have an do-nothing recipe. intermediate = "%s.intermediate" % (command if command else self.target) - self.WriteLn('%s: %s' % (' '.join(outputs), intermediate)) + self.WriteLn('{}: {}'.format(' '.join(outputs), intermediate)) self.WriteLn('\t%s' % '@:'); - self.WriteLn('%s: %s' % ('.INTERMEDIATE', intermediate)) + self.WriteLn('{}: {}'.format('.INTERMEDIATE', intermediate)) self.WriteLn('%s: %s%s' % (intermediate, ' '.join(inputs), force_append)) actions.insert(0, '$(call do_cmd,touch)') @@ -1802,7 +1802,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD default_cpp_ext = ext self.WriteLn('LOCAL_CPP_EXTENSION := ' + default_cpp_ext) - self.WriteList(map(self.Absolutify, filter(Compilable, all_sources)), + self.WriteList(list(map(self.Absolutify, list(filter(Compilable, all_sources)))), 'LOCAL_SRC_FILES') # Filter out those which do not match prefix and suffix and produce @@ -1870,7 +1870,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD # export foo := a\ b # it does not -- the backslash is written to the env as literal character. # So don't escape spaces in |env[k]|. - self.WriteLn('%s: export %s := %s' % (QuoteSpaces(target), k, v)) + self.WriteLn('{}: export {} := {}'.format(QuoteSpaces(target), k, v)) def Objectify(self, path): @@ -1878,7 +1878,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD if '$(' in path: path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/' % self.toolset) if not '$(obj)' in path: - path = '$(obj).%s/$(TARGET)/%s' % (self.toolset, path) + path = '$(obj).{}/$(TARGET)/{}'.format(self.toolset, path) return path @@ -1889,7 +1889,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/pch-%s' % (self.toolset, lang)) return path - return '$(obj).%s/$(TARGET)/pch-%s/%s' % (self.toolset, lang, path) + return '$(obj).{}/$(TARGET)/pch-{}/{}'.format(self.toolset, lang, path) def Absolutify(self, path): @@ -1921,7 +1921,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD (self.flavor != 'mac' or self.toolset != 'target')): # Install all shared libs into a common directory (per toolset) for # convenient access with LD_LIBRARY_PATH. - return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias) + return '$(builddir)/lib.{}/{}'.format(self.toolset, self.alias) return '$(builddir)/' + self.alias @@ -1957,7 +1957,7 @@ def PerformBuild(data, configurations, params): if options.toplevel_dir and options.toplevel_dir != '.': arguments += '-C', options.toplevel_dir arguments.append('BUILDTYPE=' + config) - print 'Building [%s]: %s' % (config, arguments) + print('Building [{}]: {}'.format(config, arguments)) subprocess.check_call(arguments) @@ -1990,7 +1990,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # away when we add verification that all targets have the # necessary configurations. default_configuration = None - toolsets = set([target_dicts[target]['toolset'] for target in target_list]) + toolsets = {target_dicts[target]['toolset'] for target in target_list} for target in target_list: spec = target_dicts[target] if spec['default_configuration'] != 'Default': @@ -2083,7 +2083,7 @@ def GenerateOutput(target_list, target_dicts, data, params): value = '$(abspath %s)' % value wrapper = wrappers.get(key) if wrapper: - value = '%s %s' % (wrapper, value) + value = '{} {}'.format(wrapper, value) del wrappers[key] if key in ('CC', 'CC.host', 'CXX', 'CXX.host'): make_global_settings += ( @@ -2092,10 +2092,10 @@ def GenerateOutput(target_list, target_dicts, data, params): env_key = key.replace('.', '_') # CC.host -> CC_host if env_key in os.environ: value = os.environ[env_key] - make_global_settings += ' %s = %s\n' % (key, value) + make_global_settings += ' {} = {}\n'.format(key, value) make_global_settings += 'endif\n' else: - make_global_settings += '%s ?= %s\n' % (key, value) + make_global_settings += '{} ?= {}\n'.format(key, value) # TODO(ukai): define cmd when only wrapper is specified in # make_global_settings. diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py index 7924aa1bcf..f57bad9731 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py @@ -291,7 +291,7 @@ def _ConfigBaseName(config_name, platform_name): def _ConfigFullName(config_name, config_data): platform_name = _ConfigPlatform(config_data) - return '%s|%s' % (_ConfigBaseName(config_name, platform_name), platform_name) + return '{}|{}'.format(_ConfigBaseName(config_name, platform_name), platform_name) def _ConfigWindowsTargetPlatformVersion(config_data): @@ -457,7 +457,7 @@ def _AddCustomBuildToolForMSVS(p, spec, primary_input, 'CommandLine': cmd, }) # Add to the properties of primary input for each config. - for config_name, c_data in spec['configurations'].iteritems(): + for config_name, c_data in spec['configurations'].items(): p.AddFileConfig(_FixPath(primary_input), _ConfigFullName(config_name, c_data), tools=[tool]) @@ -554,7 +554,7 @@ def _GenerateNativeRulesForMSVS(p, rules, output_dir, spec, options): spec: the project dict options: global generator options """ - rules_filename = '%s%s.rules' % (spec['target_name'], + rules_filename = '{}{}.rules'.format(spec['target_name'], options.suffix) rules_file = MSVSToolFile.Writer(os.path.join(output_dir, rules_filename), spec['target_name']) @@ -600,7 +600,7 @@ def _GenerateExternalRules(rules, output_dir, spec, options: global generator options actions_to_add: The list of actions we will add to. """ - filename = '%s_rules%s.mk' % (spec['target_name'], options.suffix) + filename = '{}_rules{}.mk'.format(spec['target_name'], options.suffix) mk_file = gyp.common.WriteOnDiff(os.path.join(output_dir, filename)) # Find cygwin style versions of some paths. mk_file.write('OutDirCygwin:=$(shell cygpath -u "$(OutDir)")\n') @@ -643,7 +643,7 @@ def _GenerateExternalRules(rules, output_dir, spec, cmd = ['"%s"' % i for i in cmd] cmd = ' '.join(cmd) # Add it to the makefile. - mk_file.write('%s: %s\n' % (' '.join(outputs), ' '.join(inputs))) + mk_file.write('{}: {}\n'.format(' '.join(outputs), ' '.join(inputs))) mk_file.write('\t%s\n\n' % cmd) # Close up the file. mk_file.close() @@ -763,8 +763,8 @@ def _EscapeVCProjCommandLineArgListItem(s): # the VCProj but cause the same problem on the final command-line. Moving # the item to the end of the list does works, but that's only possible if # there's only one such item. Let's just warn the user. - print >> sys.stderr, ('Warning: MSVS may misinterpret the odd number of ' + - 'quotes in ' + s) + print(('Warning: MSVS may misinterpret the odd number of ' + + 'quotes in ' + s), file=sys.stderr) return s @@ -878,7 +878,7 @@ def _FilterActionsFromExcluded(excluded_sources, actions_to_add): Returns: excluded_sources with files that have actions attached removed. """ - must_keep = OrderedSet(_FixPaths(actions_to_add.keys())) + must_keep = OrderedSet(_FixPaths(list(actions_to_add.keys()))) return [s for s in excluded_sources if s not in must_keep] @@ -979,9 +979,9 @@ def _ValidateSourcesForMSVSProject(spec, version): basenames.setdefault(basename, []).append(source) error = '' - for basename, files in basenames.iteritems(): + for basename, files in basenames.items(): if len(files) > 1: - error += ' %s: %s\n' % (basename, ' '.join(files)) + error += ' {}: {}\n'.format(basename, ' '.join(files)) if error: print('static library %s has several files with the same basename:\n' % @@ -1011,7 +1011,7 @@ def _GenerateMSVSProject(project, options, version, generator_flags): relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, project_dir) config_type = _GetMSVSConfigurationType(spec, project.build_file) - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config) # MSVC08 and prior version cannot handle duplicate basenames in the same @@ -1380,10 +1380,10 @@ def _ConvertToolsToExpectedForm(tools): A list of Tool objects. """ tool_list = [] - for tool, settings in tools.iteritems(): + for tool, settings in tools.items(): # Collapse settings with lists. settings_fixed = {} - for setting, value in settings.iteritems(): + for setting, value in settings.items(): if type(value) == list: if ((tool == 'VCLinkerTool' and setting == 'AdditionalDependencies') or @@ -1530,7 +1530,7 @@ def _AdjustSourcesAndConvertToFilterHierarchy( # such as ../../src/modules/module1 etc. if version.UsesVcxproj(): while all([isinstance(s, MSVSProject.Filter) for s in sources]) \ - and len(set([s.name for s in sources])) == 1: + and len({s.name for s in sources}) == 1: assert all([len(s.contents) == 1 for s in sources]) sources = [s.contents[0] for s in sources] else: @@ -1558,7 +1558,7 @@ def _IdlFilesHandledNonNatively(spec, sources): def _GetPrecompileRelatedFiles(spec): # Gather a list of precompiled header related sources. precompiled_related = [] - for _, config in spec['configurations'].iteritems(): + for _, config in spec['configurations'].items(): for k in precomp_keys: f = config.get(k) if f: @@ -1569,7 +1569,7 @@ def _GetPrecompileRelatedFiles(spec): def _ExcludeFilesFromBeingBuilt(p, spec, excluded_sources, excluded_idl, list_excluded): exclusions = _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl) - for file_name, excluded_configs in exclusions.iteritems(): + for file_name, excluded_configs in exclusions.items(): if (not list_excluded and len(excluded_configs) == len(spec['configurations'])): # If we're not listing excluded files, then they won't appear in the @@ -1586,7 +1586,7 @@ def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): # Exclude excluded sources from being built. for f in excluded_sources: excluded_configs = [] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): precomped = [_FixPath(config.get(i, '')) for i in precomp_keys] # Don't do this for ones that are precompiled header related. if f not in precomped: @@ -1596,7 +1596,7 @@ def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): # Exclude them now. for f in excluded_idl: excluded_configs = [] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): excluded_configs.append((config_name, config)) exclusions[f] = excluded_configs return exclusions @@ -1605,7 +1605,7 @@ def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): def _AddToolFilesToMSVS(p, spec): # Add in tool files (rules). tool_files = OrderedSet() - for _, config in spec['configurations'].iteritems(): + for _, config in spec['configurations'].items(): for f in config.get('msvs_tool_files', []): tool_files.add(f) for f in tool_files: @@ -1618,7 +1618,7 @@ def _HandlePreCompiledHeaders(p, sources, spec): # kind (i.e. C vs. C++) as the precompiled header source stub needs # to have use of precompiled headers disabled. extensions_excluded_from_precompile = [] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): source = config.get('msvs_precompiled_source') if source: source = _FixPath(source) @@ -1639,7 +1639,7 @@ def _HandlePreCompiledHeaders(p, sources, spec): else: basename, extension = os.path.splitext(source) if extension in extensions_excluded_from_precompile: - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): tool = MSVSProject.Tool('VCCLCompilerTool', {'UsePrecompiledHeader': '0', 'ForcedIncludeFiles': '$(NOINHERIT)'}) @@ -1690,7 +1690,7 @@ def _WriteMSVSUserFile(project_path, version, spec): return # Nothing to add # Write out the user file. user_file = _CreateMSVSUserFile(project_path, version, spec) - for config_name, c_data in spec['configurations'].iteritems(): + for config_name, c_data in spec['configurations'].items(): user_file.AddDebugSettings(_ConfigFullName(config_name, c_data), action, environment, working_directory) user_file.WriteIfChanged() @@ -1715,14 +1715,14 @@ def _GetCopies(spec): src_bare = src[:-1] base_dir = posixpath.split(src_bare)[0] outer_dir = posixpath.split(src_bare)[1] - cmd = 'cd "%s" && xcopy /e /f /y "%s" "%s\\%s\\"' % ( + cmd = 'cd "{}" && xcopy /e /f /y "{}" "{}\\{}\\"'.format( _FixPath(base_dir), outer_dir, _FixPath(dst), outer_dir) copies.append(([src], ['dummy_copies', dst], cmd, - 'Copying %s to %s' % (src, dst))) + 'Copying {} to {}'.format(src, dst))) else: - cmd = 'mkdir "%s" 2>nul & set ERRORLEVEL=0 & copy /Y "%s" "%s"' % ( + cmd = 'mkdir "{}" 2>nul & set ERRORLEVEL=0 & copy /Y "{}" "{}"'.format( _FixPath(cpy['destination']), _FixPath(src), _FixPath(dst)) - copies.append(([src], [dst], cmd, 'Copying %s to %s' % (src, dst))) + copies.append(([src], [dst], cmd, 'Copying {} to {}'.format(src, dst))) return copies @@ -1741,7 +1741,7 @@ def _GetPathDict(root, path): def _DictsToFolders(base_path, bucket, flat): # Convert to folders recursively. children = [] - for folder, contents in bucket.iteritems(): + for folder, contents in bucket.items(): if type(contents) == dict: folder_children = _DictsToFolders(os.path.join(base_path, folder), contents, flat) @@ -1763,8 +1763,8 @@ def _CollapseSingles(parent, node): # such projects up one level. if (type(node) == dict and len(node) == 1 and - node.keys()[0] == parent + '.vcproj'): - return node[node.keys()[0]] + list(node.keys())[0] == parent + '.vcproj'): + return node[list(node.keys())[0]] if type(node) != dict: return node for child in node: @@ -1783,8 +1783,8 @@ def _GatherSolutionFolders(sln_projects, project_objects, flat): # Walk down from the top until we hit a folder that has more than one entry. # In practice, this strips the top-level "src/" dir from the hierarchy in # the solution. - while len(root) == 1 and type(root[root.keys()[0]]) == dict: - root = root[root.keys()[0]] + while len(root) == 1 and type(root[list(root.keys())[0]]) == dict: + root = root[list(root.keys())[0]] # Collapse singles. root = _CollapseSingles('', root) # Merge buckets until everything is a root entry. @@ -1813,10 +1813,10 @@ def _GetPlatformOverridesOfProject(spec): # Prepare a dict indicating which project configurations are used for which # solution configurations for this target. config_platform_overrides = {} - for config_name, c in spec['configurations'].iteritems(): + for config_name, c in spec['configurations'].items(): config_fullname = _ConfigFullName(config_name, c) platform = c.get('msvs_target_platform', _ConfigPlatform(c)) - fixed_config_fullname = '%s|%s' % ( + fixed_config_fullname = '{}|{}'.format( _ConfigBaseName(config_name, _ConfigPlatform(c)), platform) config_platform_overrides[config_fullname] = fixed_config_fullname return config_platform_overrides @@ -1952,7 +1952,7 @@ def PerformBuild(data, configurations, params): msvs_version = params['msvs_version'] devenv = os.path.join(msvs_version.path, 'Common7', 'IDE', 'devenv.com') - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): (build_file_root, build_file_ext) = os.path.splitext(build_file) if build_file_ext != '.gyp': continue @@ -1962,7 +1962,7 @@ def PerformBuild(data, configurations, params): for config in configurations: arguments = [devenv, sln_path, '/Build', config] - print 'Building [%s]: %s' % (config, arguments) + print('Building [{}]: {}'.format(config, arguments)) rtn = subprocess.check_call(arguments) @@ -2014,7 +2014,7 @@ def GenerateOutput(target_list, target_dicts, data, params): configs = set() for qualified_target in target_list: spec = target_dicts[qualified_target] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): configs.add(_ConfigFullName(config_name, config)) configs = list(configs) @@ -2057,7 +2057,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if generator_flags.get('msvs_error_on_missing_sources', False): raise GypError(error_message) else: - print >> sys.stdout, "Warning: " + error_message + print("Warning: " + error_message, file=sys.stdout) def _GenerateMSBuildFiltersFile(filters_path, source_files, @@ -2109,7 +2109,7 @@ def _AppendFiltersForMSBuild(parent_filter_name, sources, rule_dependencies, if not parent_filter_name: filter_name = source.name else: - filter_name = '%s\\%s' % (parent_filter_name, source.name) + filter_name = '{}\\{}'.format(parent_filter_name, source.name) # Add the filter to the group. filter_group.append( ['Filter', {'Include': filter_name}, @@ -2213,7 +2213,7 @@ def _GenerateRulesForMSBuild(output_dir, options, spec, _AdjustSourcesForRules(rules, sources, excluded_sources, True) -class MSBuildRule(object): +class MSBuildRule: """Used to store information used to generate an MSBuild rule. Attributes: @@ -2373,7 +2373,7 @@ def _GenerateMSBuildRuleTargetsFile(targets_path, msbuild_rules): {'Condition': "'@(%s)' != '' and '%%(%s.ExcludedFromBuild)' != " "'true'" % (rule.tlog, rule.tlog), 'File': '$(IntDir)$(ProjectName).write.1.tlog', - 'Lines': "^%%(%s.Source);@(%s->'%%(Fullpath)')" % (rule.tlog, + 'Lines': "^%({}.Source);@({}->'%(Fullpath)')".format(rule.tlog, rule.tlog) } ] @@ -2382,7 +2382,7 @@ def _GenerateMSBuildRuleTargetsFile(targets_path, msbuild_rules): {'Condition': "'@(%s)' != '' and '%%(%s.ExcludedFromBuild)' != " "'true'" % (rule.tlog, rule.tlog), 'File': '$(IntDir)$(ProjectName).read.1.tlog', - 'Lines': "^%%(%s.Source);%%(%s.Inputs)" % (rule.tlog, rule.tlog) + 'Lines': "^%({}.Source);%({}.Inputs)".format(rule.tlog, rule.tlog) } ] command_and_input_section = [ @@ -2403,7 +2403,7 @@ def _GenerateMSBuildRuleTargetsFile(targets_path, msbuild_rules): 'BeforeTargets': '$(%s)' % rule.before_targets, 'AfterTargets': '$(%s)' % rule.after_targets, 'Condition': "'@(%s)' != ''" % rule_name, - 'DependsOnTargets': '$(%s);%s' % (rule.depends_on, + 'DependsOnTargets': '$({});{}'.format(rule.depends_on, rule.compute_output), 'Outputs': target_outputs, 'Inputs': target_inputs @@ -2654,9 +2654,9 @@ def _GetConfigurationCondition(name, settings): def _GetMSBuildProjectConfigurations(configurations): group = ['ItemGroup', {'Label': 'ProjectConfigurations'}] - for (name, settings) in sorted(configurations.iteritems()): + for (name, settings) in sorted(configurations.items()): configuration, platform = _GetConfigurationAndPlatform(name, settings) - designation = '%s|%s' % (configuration, platform) + designation = '{}|{}'.format(configuration, platform) group.append( ['ProjectConfiguration', {'Include': designation}, ['Configuration', configuration], @@ -2706,7 +2706,7 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): platform_name = None msvs_windows_sdk_version = None - for configuration in spec['configurations'].itervalues(): + for configuration in spec['configurations'].values(): platform_name = platform_name or _ConfigPlatform(configuration) msvs_windows_sdk_version = (msvs_windows_sdk_version or _ConfigWindowsTargetPlatformVersion(configuration)) @@ -2724,7 +2724,7 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): def _GetMSBuildConfigurationDetails(spec, build_file): properties = {} - for name, settings in spec['configurations'].iteritems(): + for name, settings in spec['configurations'].items(): msbuild_attributes = _GetMSBuildAttributes(spec, settings, build_file) condition = _GetConfigurationCondition(name, settings) character_set = msbuild_attributes.get('CharacterSet') @@ -2758,9 +2758,9 @@ def _GetMSBuildPropertySheets(configurations): user_props = r'$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props' additional_props = {} props_specified = False - for name, settings in sorted(configurations.iteritems()): + for name, settings in sorted(configurations.items()): configuration = _GetConfigurationCondition(name, settings) - if settings.has_key('msbuild_props'): + if 'msbuild_props' in settings: additional_props[configuration] = _FixPaths(settings['msbuild_props']) props_specified = True else: @@ -2780,7 +2780,7 @@ def _GetMSBuildPropertySheets(configurations): ] else: sheets = [] - for condition, props in additional_props.iteritems(): + for condition, props in additional_props.items(): import_group = [ 'ImportGroup', {'Label': 'PropertySheets', @@ -2813,7 +2813,7 @@ def _ConvertMSVSBuildAttributes(spec, config, build_file): elif a == 'ConfigurationType': msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a]) else: - print 'Warning: Do not know how to convert MSVS attribute ' + a + print('Warning: Do not know how to convert MSVS attribute ' + a) return msbuild_attributes @@ -2906,7 +2906,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): new_paths = '$(ExecutablePath);' + ';'.join(new_paths) properties = {} - for (name, configuration) in sorted(configurations.iteritems()): + for (name, configuration) in sorted(configurations.items()): condition = _GetConfigurationCondition(name, configuration) attributes = _GetMSBuildAttributes(spec, configuration, build_file) msbuild_settings = configuration['finalized_msbuild_settings'] @@ -2928,7 +2928,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): _AddConditionalProperty(properties, condition, 'ExecutablePath', new_paths) tool_settings = msbuild_settings.get('', {}) - for name, value in sorted(tool_settings.iteritems()): + for name, value in sorted(tool_settings.items()): formatted_value = _GetValueFormattedForMSBuild('', name, value) _AddConditionalProperty(properties, condition, name, formatted_value) return _GetMSBuildPropertyGroup(spec, None, properties) @@ -2986,18 +2986,18 @@ def _GetMSBuildPropertyGroup(spec, label, properties): # # Self references are ignored. Self reference is used in a few places to # append to the default value. I.e. PATH=$(PATH);other_path - edges.update(set([v for v in MSVS_VARIABLE_REFERENCE.findall(value) - if v in properties and v != node])) + edges.update({v for v in MSVS_VARIABLE_REFERENCE.findall(value) + if v in properties and v != node}) return edges properties_ordered = gyp.common.TopologicallySorted( - properties.keys(), GetEdges) + list(properties.keys()), GetEdges) # Walk properties in the reverse of a topological sort on # user_of_variable -> used_variable as this ensures variables are # defined before they are used. # NOTE: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) for name in reversed(properties_ordered): values = properties[name] - for value, conditions in sorted(values.iteritems()): + for value, conditions in sorted(values.items()): if len(conditions) == num_configurations: # If the value is the same all configurations, # just add one unconditional entry. @@ -3010,18 +3010,18 @@ def _GetMSBuildPropertyGroup(spec, label, properties): def _GetMSBuildToolSettingsSections(spec, configurations): groups = [] - for (name, configuration) in sorted(configurations.iteritems()): + for (name, configuration) in sorted(configurations.items()): msbuild_settings = configuration['finalized_msbuild_settings'] group = ['ItemDefinitionGroup', {'Condition': _GetConfigurationCondition(name, configuration)} ] - for tool_name, tool_settings in sorted(msbuild_settings.iteritems()): + for tool_name, tool_settings in sorted(msbuild_settings.items()): # Skip the tool named '' which is a holder of global settings handled # by _GetMSBuildConfigurationGlobalProperties. if tool_name: if tool_settings: tool = [tool_name] - for name, value in sorted(tool_settings.iteritems()): + for name, value in sorted(tool_settings.items()): formatted_value = _GetValueFormattedForMSBuild(tool_name, name, value) tool.append([name, formatted_value]) @@ -3054,7 +3054,7 @@ def _FinalizeMSBuildSettings(spec, configuration): for ignored_setting in ignored_settings: value = configuration.get(ignored_setting) if value: - print ('Warning: The automatic conversion to MSBuild does not handle ' + print('Warning: The automatic conversion to MSBuild does not handle ' '%s. Ignoring setting of %s' % (ignored_setting, str(value))) defines = [_EscapeCppDefineForMSBuild(d) for d in defines] @@ -3221,7 +3221,7 @@ def _AddSources2(spec, sources, exclusions, grouped_sources, {'Condition': condition}, 'true']) # Add precompile if needed - for config_name, configuration in spec['configurations'].iteritems(): + for config_name, configuration in spec['configurations'].items(): precompiled_source = configuration.get('msvs_precompiled_source', '') if precompiled_source != '': precompiled_source = _FixPath(precompiled_source) @@ -3267,7 +3267,7 @@ def _GetMSBuildProjectReferences(project): ['Project', guid], ['ReferenceOutputAssembly', 'false'] ] - for config in dependency.spec.get('configurations', {}).itervalues(): + for config in dependency.spec.get('configurations', {}).values(): # If it's disabled in any config, turn it off in the reference. if config.get('msvs_2010_disable_uldi_when_referenced', 0): project_ref.append(['UseLibraryDependencyInputs', 'false']) @@ -3333,7 +3333,7 @@ def _GenerateMSBuildProject(project, options, version, generator_flags): extension_to_rule_name) missing_sources = _VerifySourcesExist(sources, project_dir) - for configuration in configurations.itervalues(): + for configuration in configurations.values(): _FinalizeMSBuildSettings(spec, configuration) # Add attributes to root element @@ -3458,7 +3458,7 @@ def _GenerateActionsForMSBuild(spec, actions_to_add): """ sources_handled_by_action = OrderedSet() actions_spec = [] - for primary_input, actions in actions_to_add.iteritems(): + for primary_input, actions in actions_to_add.items(): inputs = OrderedSet() outputs = OrderedSet() descriptions = [] diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py index 0555a4a90d..ef8549771c 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py @@ -95,10 +95,10 @@ def Define(d, flavor): def AddArch(output, arch): """Adds an arch string to an output path.""" output, extension = os.path.splitext(output) - return '%s.%s%s' % (output, arch, extension) + return '{}.{}{}'.format(output, arch, extension) -class Target(object): +class Target: """Target represents the paths used within a single gyp target. Conceptually, building a single target A is a series of steps: @@ -208,7 +208,7 @@ class Target(object): # an output file; the result can be namespaced such that it is unique # to the input file name as well as the output target name. -class NinjaWriter(object): +class NinjaWriter: def __init__(self, hash_for_rules, target_outputs, base_dir, build_dir, output_file, toplevel_build, output_file_name, flavor, toplevel_dir=None): @@ -350,7 +350,7 @@ class NinjaWriter(object): Uses a stamp file if necessary.""" - assert targets == filter(None, targets), targets + assert targets == [_f for _f in targets if _f], targets if len(targets) == 0: assert not order_only return None @@ -362,7 +362,7 @@ class NinjaWriter(object): def _SubninjaNameForArch(self, arch): output_file_base = os.path.splitext(self.output_file_name)[0] - return '%s.%s.ninja' % (output_file_base, arch) + return '{}.{}.ninja'.format(output_file_base, arch) def WriteSpec(self, spec, config_name, generator_flags): """The main entry point for NinjaWriter: write the build rules for a spec. @@ -403,12 +403,12 @@ class NinjaWriter(object): if self.flavor == 'mac': self.archs = self.xcode_settings.GetActiveArchs(config_name) if len(self.archs) > 1: - self.arch_subninjas = dict( - (arch, ninja_syntax.Writer( + self.arch_subninjas = { + arch: ninja_syntax.Writer( OpenOutput(os.path.join(self.toplevel_build, self._SubninjaNameForArch(arch)), - 'w'))) - for arch in self.archs) + 'w')) + for arch in self.archs} # Compute predepends for all rules. # actions_depends is the dependencies this target depends on before running @@ -427,8 +427,8 @@ class NinjaWriter(object): compile_depends.append(target.PreCompileInput()) if target.uses_cpp: self.target.uses_cpp = True - actions_depends = filter(None, actions_depends) - compile_depends = filter(None, compile_depends) + actions_depends = [_f for _f in actions_depends if _f] + compile_depends = [_f for _f in compile_depends if _f] actions_depends = self.WriteCollapsedDependencies('actions_depends', actions_depends) compile_depends = self.WriteCollapsedDependencies('compile_depends', @@ -455,8 +455,8 @@ class NinjaWriter(object): try: sources = extra_sources + spec.get('sources', []) except TypeError: - print 'extra_sources: ', str(extra_sources) - print 'spec.get("sources"): ', str(spec.get('sources')) + print('extra_sources: ', str(extra_sources)) + print('spec.get("sources"): ', str(spec.get('sources'))) raise if sources: if self.flavor == 'mac' and len(self.archs) > 1: @@ -485,8 +485,8 @@ class NinjaWriter(object): if self.flavor != 'mac' or len(self.archs) == 1: link_deps += [self.GypPathToNinja(o) for o in obj_outputs] else: - print "Warning: Actions/rules writing object files don't work with " \ - "multiarch targets, dropping. (target %s)" % spec['target_name'] + print("Warning: Actions/rules writing object files don't work with " \ + "multiarch targets, dropping. (target %s)" % spec['target_name']) elif self.flavor == 'mac' and len(self.archs) > 1: link_deps = collections.defaultdict(list) @@ -544,7 +544,7 @@ class NinjaWriter(object): if self.msvs_settings.HasExplicitIdlRulesOrActions(spec): return [] outputs = [] - for source in filter(lambda x: x.endswith('.idl'), spec['sources']): + for source in [x for x in spec['sources'] if x.endswith('.idl')]: self._WinIdlRule(source, prebuild, outputs) return outputs @@ -595,9 +595,9 @@ class NinjaWriter(object): if self.toolset != 'target': verb += '(%s)' % self.toolset if message: - return '%s %s' % (verb, self.ExpandSpecial(message)) + return '{} {}'.format(verb, self.ExpandSpecial(message)) else: - return '%s %s: %s' % (verb, self.name, fallback) + return '{} {}: {}'.format(verb, self.name, fallback) def WriteActions(self, actions, extra_sources, prebuild, extra_mac_bundle_resources): @@ -606,7 +606,7 @@ class NinjaWriter(object): all_outputs = [] for action in actions: # First write out a rule for the action. - name = '%s_%s' % (action['action_name'], self.hash_for_rules) + name = '{}_{}'.format(action['action_name'], self.hash_for_rules) description = self.GenerateDescription('ACTION', action.get('message', None), name) @@ -647,7 +647,7 @@ class NinjaWriter(object): continue # First write out a rule for the rule action. - name = '%s_%s' % (rule['rule_name'], self.hash_for_rules) + name = '{}_{}'.format(rule['rule_name'], self.hash_for_rules) args = rule['action'] description = self.GenerateDescription( @@ -667,7 +667,7 @@ class NinjaWriter(object): # must vary per source file. # Compute the list of variables we'll need to provide. special_locals = ('source', 'root', 'dirname', 'ext', 'name') - needed_variables = set(['source']) + needed_variables = {'source'} for argument in args: for var in special_locals: if '${%s}' % var in argument: @@ -791,10 +791,10 @@ class NinjaWriter(object): copy_headers = spec['mac_framework_headers'] output = self.GypPathToUniqueOutput('headers.hmap') self.xcode_settings.header_map_path = output - all_headers = map(self.GypPathToNinja, - filter(lambda x:x.endswith(('.h')), all_sources)) + all_headers = list(map(self.GypPathToNinja, + [x for x in all_sources if x.endswith('.h')])) variables = [('framework', framework), - ('copy_headers', map(self.GypPathToNinja, copy_headers))] + ('copy_headers', list(map(self.GypPathToNinja, copy_headers)))] outputs.extend(self.ninja.build( output, 'compile_ios_framework_headers', all_headers, variables=variables, order_only=prebuild)) @@ -810,7 +810,7 @@ class NinjaWriter(object): for output, res in gyp.xcode_emulation.GetMacBundleResources( generator_default_variables['PRODUCT_DIR'], - self.xcode_settings, map(self.GypPathToNinja, resources)): + self.xcode_settings, list(map(self.GypPathToNinja, resources))): output = self.ExpandSpecial(output) if os.path.splitext(output)[-1] != '.xcassets': self.ninja.build(output, 'mac_tool', res, @@ -838,7 +838,7 @@ class NinjaWriter(object): 'XCASSETS_LAUNCH_IMAGE': 'launch-image', } settings = self.xcode_settings.xcode_settings[self.config_name] - for settings_key, arg_name in settings_to_arg.iteritems(): + for settings_key, arg_name in settings_to_arg.items(): value = settings.get(settings_key) if value: extra_arguments[arg_name] = value @@ -918,10 +918,10 @@ class NinjaWriter(object): self.ninja, config_name, config, sources, predepends, precompiled_header, spec) else: - return dict((arch, self.WriteSourcesForArch( + return {arch: self.WriteSourcesForArch( self.arch_subninjas[arch], config_name, config, sources, predepends, - precompiled_header, spec, arch=arch)) - for arch in self.archs) + precompiled_header, spec, arch=arch) + for arch in self.archs} def WriteSourcesForArch(self, ninja_file, config_name, config, sources, predepends, precompiled_header, spec, arch=None): @@ -978,7 +978,7 @@ class NinjaWriter(object): [Define(d, self.flavor) for d in defines]) if self.flavor == 'win': self.WriteVariableList(ninja_file, 'asmflags', - map(self.ExpandSpecial, asmflags)) + list(map(self.ExpandSpecial, asmflags))) self.WriteVariableList(ninja_file, 'rcflags', [QuoteShellArgument(self.ExpandSpecial(f), self.flavor) for f in self.msvs_settings.GetRcflags(config_name, @@ -1013,18 +1013,18 @@ class NinjaWriter(object): arflags = config.get('arflags', []) self.WriteVariableList(ninja_file, 'cflags', - map(self.ExpandSpecial, cflags)) + list(map(self.ExpandSpecial, cflags))) self.WriteVariableList(ninja_file, 'cflags_c', - map(self.ExpandSpecial, cflags_c)) + list(map(self.ExpandSpecial, cflags_c))) self.WriteVariableList(ninja_file, 'cflags_cc', - map(self.ExpandSpecial, cflags_cc)) + list(map(self.ExpandSpecial, cflags_cc))) if self.flavor == 'mac': self.WriteVariableList(ninja_file, 'cflags_objc', - map(self.ExpandSpecial, cflags_objc)) + list(map(self.ExpandSpecial, cflags_objc))) self.WriteVariableList(ninja_file, 'cflags_objcc', - map(self.ExpandSpecial, cflags_objcc)) + list(map(self.ExpandSpecial, cflags_objcc))) self.WriteVariableList(ninja_file, 'arflags', - map(self.ExpandSpecial, arflags)) + list(map(self.ExpandSpecial, arflags))) ninja_file.newline() outputs = [] has_rc_source = False @@ -1233,7 +1233,7 @@ class NinjaWriter(object): ldflags.append('-Wl,-rpath=%s' % self.target_rpath) ldflags.append('-Wl,-rpath-link=%s' % rpath) self.WriteVariableList(ninja_file, 'ldflags', - map(self.ExpandSpecial, ldflags)) + list(map(self.ExpandSpecial, ldflags))) library_dirs = config.get('library_dirs', []) if self.flavor == 'win': @@ -1247,8 +1247,8 @@ class NinjaWriter(object): self.flavor) for l in library_dirs] - libraries = gyp.common.uniquer(map(self.ExpandSpecial, - spec.get('libraries', []))) + libraries = gyp.common.uniquer(list(map(self.ExpandSpecial, + spec.get('libraries', [])))) if self.flavor == 'mac': libraries = self.xcode_settings.AdjustLibraries(libraries, config_name) elif self.flavor == 'win': @@ -1525,7 +1525,7 @@ class NinjaWriter(object): if type in ('static_library', 'loadable_module', 'shared_library', 'executable'): - return '%s%s%s' % (prefix, target, extension) + return '{}{}{}'.format(prefix, target, extension) elif type == 'none': return '%s.stamp' % target else: @@ -1943,7 +1943,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value) # Support wrappers from environment variables too. - for key, value in os.environ.iteritems(): + for key, value in os.environ.items(): if key.lower().endswith('_wrapper'): key_prefix = key[:-len('_wrapper')] key_prefix = re.sub(r'\.HOST$', '.host', key_prefix) @@ -1963,7 +1963,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, configs, generator_flags) cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles( toplevel_build, generator_flags, shared_system_includes, OpenOutput) - for arch, path in sorted(cl_paths.iteritems()): + for arch, path in sorted(cl_paths.items()): if clang_cl: # If we have selected clang-cl, use that instead. path = clang_cl @@ -2437,7 +2437,7 @@ def PerformBuild(data, configurations, params): for config in configurations: builddir = os.path.join(options.toplevel_dir, 'out', config) arguments = ['ninja', '-C', builddir] - print 'Building [%s]: %s' % (config, arguments) + print('Building [{}]: {}'.format(config, arguments)) subprocess.check_call(arguments) @@ -2465,7 +2465,7 @@ def GenerateOutput(target_list, target_dicts, data, params): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: - config_names = target_dicts[target_list[0]]['configurations'].keys() + config_names = list(target_dicts[target_list[0]]['configurations'].keys()) if params['parallel']: try: pool = multiprocessing.Pool(len(config_names)) @@ -2474,7 +2474,7 @@ def GenerateOutput(target_list, target_dicts, data, params): arglists.append( (target_list, target_dicts, data, params, config_name)) pool.map(CallGenerateOutputForConfig, arglists) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: pool.terminate() raise e else: diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py index db99d6ab81..6e12b54efb 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py @@ -109,7 +109,7 @@ def CreateXCConfigurationList(configuration_names): return xccl -class XcodeProject(object): +class XcodeProject: def __init__(self, gyp_path, path, build_file_dict): self.gyp_path = gyp_path self.path = path @@ -129,7 +129,7 @@ class XcodeProject(object): try: os.makedirs(self.path) self.created_dir = True - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise @@ -183,7 +183,7 @@ class XcodeProject(object): # the tree tree view for UI display. # Any values set globally are applied to all configurations, then any # per-configuration values are applied. - for xck, xcv in self.build_file_dict.get('xcode_settings', {}).iteritems(): + for xck, xcv in self.build_file_dict.get('xcode_settings', {}).items(): xccl.SetBuildSetting(xck, xcv) if 'xcode_config_file' in self.build_file_dict: config_ref = self.project.AddOrGetFileInRootGroup( @@ -196,8 +196,8 @@ class XcodeProject(object): build_file_configurations.get(config_name, {}) if build_file_configuration_named: xcc = xccl.ConfigurationNamed(config_name) - for xck, xcv in build_file_configuration_named.get('xcode_settings', - {}).iteritems(): + for xck, xcv in (build_file_configuration_named.get('xcode_settings', + {})).items(): xcc.SetBuildSetting(xck, xcv) if 'xcode_config_file' in build_file_configuration_named: config_ref = self.project.AddOrGetFileInRootGroup( @@ -273,7 +273,7 @@ class XcodeProject(object): script = script + "\n".join( ['export %s="%s"' % (key, gyp.xcodeproj_file.ConvertVariablesToShellSyntax(val)) - for (key, val) in command.get('environment').iteritems()]) + "\n" + for (key, val) in command.get('environment').items()]) + "\n" # Some test end up using sockets, files on disk, etc. and can get # confused if more then one test runs at a time. The generator @@ -454,7 +454,7 @@ sys.exit(subprocess.call(sys.argv[1:]))" """ same = False try: same = filecmp.cmp(pbxproj_path, new_pbxproj_path, False) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: raise @@ -473,10 +473,10 @@ sys.exit(subprocess.call(sys.argv[1:]))" """ # # No way to get the umask without setting a new one? Set a safe one # and then set it back to the old value. - umask = os.umask(077) + umask = os.umask(0o77) os.umask(umask) - os.chmod(new_pbxproj_path, 0666 & ~umask) + os.chmod(new_pbxproj_path, 0o666 & ~umask) os.rename(new_pbxproj_path, pbxproj_path) except Exception: @@ -566,7 +566,7 @@ def EscapeXcodeDefine(s): def PerformBuild(data, configurations, params): options = params['options'] - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): (build_file_root, build_file_ext) = os.path.splitext(build_file) if build_file_ext != '.gyp': continue @@ -577,7 +577,7 @@ def PerformBuild(data, configurations, params): for config in configurations: arguments = ['xcodebuild', '-project', xcodeproj_path] arguments += ['-configuration', config] - print "Building [%s]: %s" % (config, arguments) + print("Building [{}]: {}".format(config, arguments)) subprocess.check_call(arguments) @@ -625,7 +625,7 @@ def GenerateOutput(target_list, target_dicts, data, params): skip_excluded_files = \ not generator_flags.get('xcode_list_excluded_files', True) xcode_projects = {} - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): (build_file_root, build_file_ext) = os.path.splitext(build_file) if build_file_ext != '.gyp': continue @@ -744,7 +744,7 @@ def GenerateOutput(target_list, target_dicts, data, params): xctarget_type = gyp.xcodeproj_file.PBXNativeTarget try: target_properties['productType'] = _types[type_bundle_key] - except KeyError, e: + except KeyError as e: gyp.common.ExceptionAppend(e, "-- unknown product type while " "writing target %s" % target_name) raise @@ -1011,7 +1011,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # TODO(mark): There's a possibilty for collision here. Consider # target "t" rule "A_r" and target "t_A" rule "r". makefile_name = '%s.make' % re.sub( - '[^a-zA-Z0-9_]', '_' , '%s_%s' % (target_name, rule['rule_name'])) + '[^a-zA-Z0-9_]', '_' , '{}_{}'.format(target_name, rule['rule_name'])) makefile_path = os.path.join(xcode_projects[build_file].path, makefile_name) # TODO(mark): try/close? Write to a temporary file and swap it only @@ -1024,7 +1024,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # target. makefile.write('all: \\\n') for concrete_output_index in \ - xrange(0, len(concrete_outputs_by_rule_source)): + range(0, len(concrete_outputs_by_rule_source)): # Only list the first (index [0]) concrete output of each input # in the "all" target. Otherwise, a parallel make (-j > 1) would # attempt to process each input multiple times simultaneously. @@ -1036,7 +1036,7 @@ def GenerateOutput(target_list, target_dicts, data, params): eol = '' else: eol = ' \\' - makefile.write(' %s%s\n' % (concrete_output, eol)) + makefile.write(' {}{}\n'.format(concrete_output, eol)) for (rule_source, concrete_outputs, message, action) in \ zip(rule['rule_sources'], concrete_outputs_by_rule_source, @@ -1047,13 +1047,13 @@ def GenerateOutput(target_list, target_dicts, data, params): # rule source. Collect the names of the directories that are # required. concrete_output_dirs = [] - for concrete_output_index in xrange(0, len(concrete_outputs)): + for concrete_output_index in range(0, len(concrete_outputs)): concrete_output = concrete_outputs[concrete_output_index] if concrete_output_index == 0: bol = '' else: bol = ' ' - makefile.write('%s%s \\\n' % (bol, concrete_output)) + makefile.write('{}{} \\\n'.format(bol, concrete_output)) concrete_output_dir = posixpath.dirname(concrete_output) if (concrete_output_dir and @@ -1066,13 +1066,13 @@ def GenerateOutput(target_list, target_dicts, data, params): # the set of additional rule inputs, if any. prerequisites = [rule_source] prerequisites.extend(rule.get('inputs', [])) - for prerequisite_index in xrange(0, len(prerequisites)): + for prerequisite_index in range(0, len(prerequisites)): prerequisite = prerequisites[prerequisite_index] if prerequisite_index == len(prerequisites) - 1: eol = '' else: eol = ' \\' - makefile.write(' %s%s\n' % (prerequisite, eol)) + makefile.write(' {}{}\n'.format(prerequisite, eol)) # Make sure that output directories exist before executing the rule # action. @@ -1288,7 +1288,7 @@ exit 1 set_define = EscapeXcodeDefine(define) xcbc.AppendBuildSetting('GCC_PREPROCESSOR_DEFINITIONS', set_define) if 'xcode_settings' in configuration: - for xck, xcv in configuration['xcode_settings'].iteritems(): + for xck, xcv in configuration['xcode_settings'].items(): xcbc.SetBuildSetting(xck, xcv) if 'xcode_config_file' in configuration: config_ref = pbxp.AddOrGetFileInRootGroup( @@ -1296,7 +1296,7 @@ exit 1 xcbc.SetBaseConfiguration(config_ref) build_files = [] - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): if build_file.endswith('.gyp'): build_files.append(build_file) diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py index a046a15cc1..d5159a6b83 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py @@ -2,14 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -from compiler.ast import Const -from compiler.ast import Dict -from compiler.ast import Discard -from compiler.ast import List -from compiler.ast import Module -from compiler.ast import Node -from compiler.ast import Stmt -import compiler +import ast as _ast_module import gyp.common import gyp.simple_copy import multiprocessing @@ -183,43 +176,33 @@ def CheckedEval(file_contents): Note that this is slower than eval() is. """ - ast = compiler.parse(file_contents) - assert isinstance(ast, Module) - c1 = ast.getChildren() - assert c1[0] is None - assert isinstance(c1[1], Stmt) - c2 = c1[1].getChildren() - assert isinstance(c2[0], Discard) - c3 = c2[0].getChildren() - assert len(c3) == 1 - return CheckNode(c3[0], []) + tree = _ast_module.parse(file_contents, mode='eval') + return CheckNode(tree.body, []) def CheckNode(node, keypath): - if isinstance(node, Dict): - c = node.getChildren() - dict = {} - for n in range(0, len(c), 2): - assert isinstance(c[n], Const) - key = c[n].getChildren()[0] - if key in dict: + if isinstance(node, _ast_module.Dict): + d = {} + for key_node, val_node in zip(node.keys, node.values): + assert isinstance(key_node, _ast_module.Constant) + key = key_node.value + if key in d: raise GypError("Key '" + key + "' repeated at level " + repr(len(keypath) + 1) + " with key path '" + '.'.join(keypath) + "'") kp = list(keypath) # Make a copy of the list for descending this node. kp.append(key) - dict[key] = CheckNode(c[n + 1], kp) - return dict - elif isinstance(node, List): - c = node.getChildren() + d[key] = CheckNode(val_node, kp) + return d + elif isinstance(node, _ast_module.List): children = [] - for index, child in enumerate(c): + for index, child in enumerate(node.elts): kp = list(keypath) # Copy list. kp.append(repr(index)) children.append(CheckNode(child, kp)) return children - elif isinstance(node, Const): - return node.getChildren()[0] + elif isinstance(node, _ast_module.Constant): + return node.value else: raise TypeError("Unknown AST node at key path '" + '.'.join(keypath) + "': " + repr(node)) @@ -233,7 +216,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, if os.path.exists(build_file_path): build_file_contents = open(build_file_path).read() else: - raise GypError("%s not found (cwd: %s)" % (build_file_path, os.getcwd())) + raise GypError("{} not found (cwd: {})".format(build_file_path, os.getcwd())) build_file_data = None try: @@ -242,10 +225,10 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, else: build_file_data = eval(build_file_contents, {'__builtins__': None}, None) - except SyntaxError, e: + except SyntaxError as e: e.filename = build_file_path raise - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend(e, 'while reading ' + build_file_path) raise @@ -265,7 +248,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, else: LoadBuildFileIncludesIntoDict(build_file_data, build_file_path, data, aux_data, None, check) - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend(e, 'while reading includes of ' + build_file_path) raise @@ -302,7 +285,7 @@ def LoadBuildFileIncludesIntoDict(subdict, subdict_path, data, aux_data, subdict_path, include) # Recurse into subdictionaries. - for k, v in subdict.iteritems(): + for k, v in subdict.items(): if type(v) is dict: LoadBuildFileIncludesIntoDict(v, subdict_path, data, aux_data, None, check) @@ -467,7 +450,7 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes, try: LoadTargetBuildFile(dependency, data, aux_data, variables, includes, depth, check, load_dependencies) - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend( e, 'while loading dependencies of %s' % build_file_path) raise @@ -488,7 +471,7 @@ def CallLoadTargetBuildFile(global_flags, signal.signal(signal.SIGINT, signal.SIG_IGN) # Apply globals so that the worker process behaves the same. - for key, value in global_flags.iteritems(): + for key, value in global_flags.items(): globals()[key] = value SetGeneratorGlobals(generator_input_info) @@ -510,12 +493,12 @@ def CallLoadTargetBuildFile(global_flags, return (build_file_path, build_file_data, dependencies) - except GypError, e: + except GypError as e: sys.stderr.write("gyp: %s\n" % e) return None - except Exception, e: - print >>sys.stderr, 'Exception:', e - print >>sys.stderr, traceback.format_exc() + except Exception as e: + print('Exception:', e, file=sys.stderr) + print(traceback.format_exc(), file=sys.stderr) return None @@ -523,7 +506,7 @@ class ParallelProcessingError(Exception): pass -class ParallelState(object): +class ParallelState: """Class to keep track of state when processing input files in parallel. If build files are loaded in parallel, use this to keep track of @@ -605,7 +588,7 @@ def LoadTargetBuildFilesParallel(build_files, data, variables, includes, depth, args = (global_flags, dependency, variables, includes, depth, check, generator_input_info), callback = parallel_state.LoadTargetBuildFileCallback) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: parallel_state.pool.terminate() raise e @@ -905,18 +888,22 @@ def ExpandVariables(input, phase, variables, build_file): stderr=subprocess.PIPE, stdin=subprocess.PIPE, cwd=build_file_dir) - except Exception, e: + except Exception as e: raise GypError("%s while executing command '%s' in %s" % (e, contents, build_file)) - p_stdout, p_stderr = p.communicate('') + p_stdout, p_stderr = p.communicate(b'') if p.wait() != 0 or p_stderr: + if isinstance(p_stderr, bytes): + p_stderr = p_stderr.decode('utf-8', errors='replace') sys.stderr.write(p_stderr) # Simulate check_call behavior, since check_call only exists # in python 2.5 and later. raise GypError("Call to '%s' returned exit status %d while in %s." % (contents, p.returncode, build_file)) + if isinstance(p_stdout, bytes): + p_stdout = p_stdout.decode('utf-8', errors='replace') replacement = p_stdout.rstrip() cached_command_results[cache_key] = replacement @@ -1019,7 +1006,7 @@ def ExpandVariables(input, phase, variables, build_file): # Convert all strings that are canonically-represented integers into integers. if type(output) is list: - for index in xrange(0, len(output)): + for index in range(0, len(output)): if IsStrCanonicalInt(output[index]): output[index] = int(output[index]) elif IsStrCanonicalInt(output): @@ -1090,13 +1077,13 @@ def EvalSingleCondition( if eval(ast_code, {'__builtins__': None}, variables): return true_dict return false_dict - except SyntaxError, e: + except SyntaxError as e: syntax_error = SyntaxError('%s while evaluating condition \'%s\' in %s ' 'at character %d.' % (str(e.args[0]), e.text, build_file, e.offset), e.filename, e.lineno, e.offset, e.text) raise syntax_error - except NameError, e: + except NameError as e: gyp.common.ExceptionAppend(e, 'while evaluating condition \'%s\' in %s' % (cond_expr_expanded, build_file)) raise GypError(e) @@ -1151,7 +1138,7 @@ def ProcessConditionsInDict(the_dict, phase, variables, build_file): def LoadAutomaticVariablesFromDict(variables, the_dict): # Any keys with plain string values in the_dict become automatic variables. # The variable name is the key name with a "_" character prepended. - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): if type(value) in (str, int, list): variables['_' + key] = value @@ -1164,7 +1151,7 @@ def LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key): # the_dict in the_dict's parent dict. If the_dict's parent is not a dict # (it could be a list or it could be parentless because it is a root dict), # the_dict_key will be None. - for key, value in the_dict.get('variables', {}).iteritems(): + for key, value in the_dict.get('variables', {}).items(): if type(value) not in (str, int, list): continue @@ -1173,7 +1160,7 @@ def LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key): if variable_name in variables: # If the variable is already set, don't set it. continue - if the_dict_key is 'variables' and variable_name in the_dict: + if the_dict_key == 'variables' and variable_name in the_dict: # If the variable is set without a % in the_dict, and the_dict is a # variables dict (making |variables| a varaibles sub-dict of a # variables dict), use the_dict's definition. @@ -1203,7 +1190,7 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, # list before we process them so that you can reference one # variable from another. They will be fully expanded by recursion # in ExpandVariables. - for key, value in the_dict['variables'].iteritems(): + for key, value in the_dict['variables'].items(): variables[key] = value # Handle the associated variables dict first, so that any variable @@ -1216,7 +1203,7 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key) - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): # Skip "variables", which was already processed if present. if key != 'variables' and type(value) is str: expanded = ExpandVariables(value, phase, variables, build_file) @@ -1274,7 +1261,7 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, # Recurse into child dicts, or process child lists which may result in # further recursion into descendant dicts. - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): # Skip "variables" and string values, which were already processed if # present. if key == 'variables' or type(value) is str: @@ -1371,12 +1358,12 @@ def QualifyDependencies(targets): for dep in dependency_sections for op in ('', '!', '/')] - for target, target_dict in targets.iteritems(): + for target, target_dict in targets.items(): target_build_file = gyp.common.BuildFile(target) toolset = target_dict['toolset'] for dependency_key in all_dependency_sections: dependencies = target_dict.get(dependency_key, []) - for index in xrange(0, len(dependencies)): + for index in range(0, len(dependencies)): dep_file, dep_target, dep_toolset = gyp.common.ResolveTarget( target_build_file, dependencies[index], toolset) if not multiple_toolsets: @@ -1411,7 +1398,7 @@ def ExpandWildcardDependencies(targets, data): dependency list, must be qualified when this function is called. """ - for target, target_dict in targets.iteritems(): + for target, target_dict in targets.items(): toolset = target_dict['toolset'] target_build_file = gyp.common.BuildFile(target) for dependency_key in dependency_sections: @@ -1473,7 +1460,7 @@ def Unify(l): def RemoveDuplicateDependencies(targets): """Makes sure every dependency appears only once in all targets's dependency lists.""" - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: @@ -1489,7 +1476,7 @@ def Filter(l, item): def RemoveSelfDependencies(targets): """Remove self dependencies from targets that have the prune_self_dependency variable set.""" - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: @@ -1502,7 +1489,7 @@ def RemoveSelfDependencies(targets): def RemoveLinkDependenciesFromNoneTargets(targets): """Remove dependencies having the 'link_dependency' attribute from the 'none' targets.""" - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: @@ -1513,7 +1500,7 @@ def RemoveLinkDependenciesFromNoneTargets(targets): Filter(target_dict[dependency_key], t) -class DependencyGraphNode(object): +class DependencyGraphNode: """ Attributes: @@ -1794,14 +1781,14 @@ def BuildDependencyList(targets): # Create a DependencyGraphNode for each target. Put it into a dict for easy # access. dependency_nodes = {} - for target, spec in targets.iteritems(): + for target, spec in targets.items(): if target not in dependency_nodes: dependency_nodes[target] = DependencyGraphNode(target) # Set up the dependency links. Targets that have no dependencies are treated # as dependent on root_node. root_node = DependencyGraphNode(None) - for target, spec in targets.iteritems(): + for target, spec in targets.items(): target_node = dependency_nodes[target] target_build_file = gyp.common.BuildFile(target) dependencies = spec.get('dependencies') @@ -1825,7 +1812,7 @@ def BuildDependencyList(targets): if not root_node.dependents: # If all targets have dependencies, add the first target as a dependent # of root_node so that the cycle can be discovered from root_node. - target = targets.keys()[0] + target = list(targets.keys())[0] target_node = dependency_nodes[target] target_node.dependencies.append(root_node) root_node.dependents.append(target_node) @@ -1844,20 +1831,20 @@ def VerifyNoGYPFileCircularDependencies(targets): # Create a DependencyGraphNode for each gyp file containing a target. Put # it into a dict for easy access. dependency_nodes = {} - for target in targets.iterkeys(): + for target in targets.keys(): build_file = gyp.common.BuildFile(target) if not build_file in dependency_nodes: dependency_nodes[build_file] = DependencyGraphNode(build_file) # Set up the dependency links. - for target, spec in targets.iteritems(): + for target, spec in targets.items(): build_file = gyp.common.BuildFile(target) build_file_node = dependency_nodes[build_file] target_dependencies = spec.get('dependencies', []) for dependency in target_dependencies: try: dependency_build_file = gyp.common.BuildFile(dependency) - except GypError, e: + except GypError as e: gyp.common.ExceptionAppend( e, 'while computing dependencies of .gyp file %s' % build_file) raise @@ -1875,7 +1862,7 @@ def VerifyNoGYPFileCircularDependencies(targets): # Files that have no dependencies are treated as dependent on root_node. root_node = DependencyGraphNode(None) - for build_file_node in dependency_nodes.itervalues(): + for build_file_node in dependency_nodes.values(): if len(build_file_node.dependencies) == 0: build_file_node.dependencies.append(root_node) root_node.dependents.append(build_file_node) @@ -1888,7 +1875,7 @@ def VerifyNoGYPFileCircularDependencies(targets): if not root_node.dependents: # If all files have dependencies, add the first file as a dependent # of root_node so that the cycle can be discovered from root_node. - file_node = dependency_nodes.values()[0] + file_node = list(dependency_nodes.values())[0] file_node.dependencies.append(root_node) root_node.dependents.append(file_node) cycles = [] @@ -2056,7 +2043,7 @@ def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True): # Make membership testing of hashables in |to| (in particular, strings) # faster. - hashable_to_set = set(x for x in to if is_hashable(x)) + hashable_to_set = {x for x in to if is_hashable(x)} for item in fro: singleton = False if type(item) in (str, int): @@ -2115,7 +2102,7 @@ def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True): def MergeDicts(to, fro, to_file, fro_file): # I wanted to name the parameter "from" but it's a Python keyword... - for k, v in fro.iteritems(): + for k, v in fro.items(): # It would be nice to do "if not k in to: to[k] = v" but that wouldn't give # copy semantics. Something else may want to merge from the |fro| dict # later, and having the same dict ref pointed to twice in the tree isn't @@ -2250,13 +2237,13 @@ def SetUpConfigurations(target, target_dict): if not 'configurations' in target_dict: target_dict['configurations'] = {'Default': {}} if not 'default_configuration' in target_dict: - concrete = [i for (i, config) in target_dict['configurations'].iteritems() + concrete = [i for (i, config) in target_dict['configurations'].items() if not config.get('abstract')] target_dict['default_configuration'] = sorted(concrete)[0] merged_configurations = {} configs = target_dict['configurations'] - for (configuration, old_configuration_dict) in configs.iteritems(): + for (configuration, old_configuration_dict) in configs.items(): # Skip abstract configurations (saves work only). if old_configuration_dict.get('abstract'): continue @@ -2264,7 +2251,7 @@ def SetUpConfigurations(target, target_dict): # Get the inheritance relationship right by making a copy of the target # dict. new_configuration_dict = {} - for (key, target_val) in target_dict.iteritems(): + for (key, target_val) in target_dict.items(): key_ext = key[-1:] if key_ext in key_suffixes: key_base = key[:-1] @@ -2285,7 +2272,7 @@ def SetUpConfigurations(target, target_dict): merged_configurations[configuration]) # Now drop all the abstract ones. - for configuration in target_dict['configurations'].keys(): + for configuration in list(target_dict['configurations'].keys()): old_configuration_dict = target_dict['configurations'][configuration] if old_configuration_dict.get('abstract'): del target_dict['configurations'][configuration] @@ -2348,7 +2335,7 @@ def ProcessListFiltersInDict(name, the_dict): lists = [] del_lists = [] - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): operation = key[-1] if operation != '!' and operation != '/': continue @@ -2396,7 +2383,7 @@ def ProcessListFiltersInDict(name, the_dict): exclude_key = list_key + '!' if exclude_key in the_dict: for exclude_item in the_dict[exclude_key]: - for index in xrange(0, len(the_list)): + for index in range(0, len(the_list)): if exclude_item == the_list[index]: # This item matches the exclude_item, so set its action to 0 # (exclude). @@ -2422,7 +2409,7 @@ def ProcessListFiltersInDict(name, the_dict): raise ValueError('Unrecognized action ' + action + ' in ' + name + \ ' key ' + regex_key) - for index in xrange(0, len(the_list)): + for index in range(0, len(the_list)): list_item = the_list[index] if list_actions[index] == action_value: # Even if the regex matches, nothing will change so continue (regex @@ -2453,7 +2440,7 @@ def ProcessListFiltersInDict(name, the_dict): # the indices of items that haven't been seen yet don't shift. That means # that things need to be prepended to excluded_list to maintain them in the # same order that they existed in the_list. - for index in xrange(len(list_actions) - 1, -1, -1): + for index in range(len(list_actions) - 1, -1, -1): if list_actions[index] == 0: # Dump anything with action 0 (exclude). Keep anything with action 1 # (include) or -1 (no include or exclude seen for the item). @@ -2466,7 +2453,7 @@ def ProcessListFiltersInDict(name, the_dict): the_dict[excluded_key] = excluded_list # Now recurse into subdicts and lists that may contain dicts. - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): if type(value) is dict: ProcessListFiltersInDict(key, value) elif type(value) is list: @@ -2523,9 +2510,9 @@ def ValidateSourcesInTarget(target, target_dict, build_file, basenames.setdefault(basename, []).append(source) error = '' - for basename, files in basenames.iteritems(): + for basename, files in basenames.items(): if len(files) > 1: - error += ' %s: %s\n' % (basename, ' '.join(files)) + error += ' {}: {}\n'.format(basename, ' '.join(files)) if error: print('static library %s has several files with the same basename:\n' % @@ -2662,7 +2649,7 @@ def TurnIntIntoStrInDict(the_dict): def TurnIntIntoStrInList(the_list): """Given list the_list, recursively converts all integers into strings. """ - for index in xrange(0, len(the_list)): + for index in range(0, len(the_list)): item = the_list[index] if type(item) is int: the_list[index] = str(item) @@ -2780,7 +2767,7 @@ def Load(build_files, variables, includes, depth, generator_input_info, check, try: LoadTargetBuildFile(build_file, data, aux_data, variables, includes, depth, check, True) - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend(e, 'while trying to load %s' % build_file) raise @@ -2802,7 +2789,7 @@ def Load(build_files, variables, includes, depth, generator_input_info, check, RemoveLinkDependenciesFromNoneTargets(targets) # Apply exclude (!) and regex (/) list filters only for dependency_sections. - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): tmp_dict = {} for key_base in dependency_sections: for op in ('', '!', '/'): diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/input_test.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/input_test.py index 4234fbb830..1bc5e3d308 100755 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/input_test.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/input_test.py @@ -22,38 +22,38 @@ class TestFindCycles(unittest.TestCase): dependency.dependents.append(dependent) def test_no_cycle_empty_graph(self): - for label, node in self.nodes.iteritems(): - self.assertEquals([], node.FindCycles()) + for label, node in self.nodes.items(): + self.assertEqual([], node.FindCycles()) def test_no_cycle_line(self): self._create_dependency(self.nodes['a'], self.nodes['b']) self._create_dependency(self.nodes['b'], self.nodes['c']) self._create_dependency(self.nodes['c'], self.nodes['d']) - for label, node in self.nodes.iteritems(): - self.assertEquals([], node.FindCycles()) + for label, node in self.nodes.items(): + self.assertEqual([], node.FindCycles()) def test_no_cycle_dag(self): self._create_dependency(self.nodes['a'], self.nodes['b']) self._create_dependency(self.nodes['a'], self.nodes['c']) self._create_dependency(self.nodes['b'], self.nodes['c']) - for label, node in self.nodes.iteritems(): - self.assertEquals([], node.FindCycles()) + for label, node in self.nodes.items(): + self.assertEqual([], node.FindCycles()) def test_cycle_self_reference(self): self._create_dependency(self.nodes['a'], self.nodes['a']) - self.assertEquals([[self.nodes['a'], self.nodes['a']]], + self.assertEqual([[self.nodes['a'], self.nodes['a']]], self.nodes['a'].FindCycles()) def test_cycle_two_nodes(self): self._create_dependency(self.nodes['a'], self.nodes['b']) self._create_dependency(self.nodes['b'], self.nodes['a']) - self.assertEquals([[self.nodes['a'], self.nodes['b'], self.nodes['a']]], + self.assertEqual([[self.nodes['a'], self.nodes['b'], self.nodes['a']]], self.nodes['a'].FindCycles()) - self.assertEquals([[self.nodes['b'], self.nodes['a'], self.nodes['b']]], + self.assertEqual([[self.nodes['b'], self.nodes['a'], self.nodes['b']]], self.nodes['b'].FindCycles()) def test_two_cycles(self): @@ -68,7 +68,7 @@ class TestFindCycles(unittest.TestCase): [self.nodes['a'], self.nodes['b'], self.nodes['a']] in cycles) self.assertTrue( [self.nodes['b'], self.nodes['c'], self.nodes['b']] in cycles) - self.assertEquals(2, len(cycles)) + self.assertEqual(2, len(cycles)) def test_big_cycle(self): self._create_dependency(self.nodes['a'], self.nodes['b']) @@ -77,7 +77,7 @@ class TestFindCycles(unittest.TestCase): self._create_dependency(self.nodes['d'], self.nodes['e']) self._create_dependency(self.nodes['e'], self.nodes['a']) - self.assertEquals([[self.nodes['a'], + self.assertEqual([[self.nodes['a'], self.nodes['b'], self.nodes['c'], self.nodes['d'], diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/mac_tool.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/mac_tool.py index 055d79cf22..514e2ec16a 100755 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/mac_tool.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/mac_tool.py @@ -30,7 +30,7 @@ def main(args): sys.exit(exit_code) -class MacTool(object): +class MacTool: """This class performs all the Mac tooling steps. The methods can either be executed directly, or dispatched from an argument list.""" @@ -163,14 +163,14 @@ class MacTool(object): def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys): """Copies the |source| Info.plist to the destination directory |dest|.""" # Read the source Info.plist into memory. - fd = open(source, 'r') + fd = open(source) lines = fd.read() fd.close() # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). plist = plistlib.readPlistFromString(lines) if keys: - plist = dict(plist.items() + json.loads(keys[0]).items()) + plist = dict(list(plist.items()) + list(json.loads(keys[0]).items())) lines = plistlib.writePlistToString(plist) # Go through all the environment variables and replace them as variables in @@ -203,7 +203,7 @@ class MacTool(object): if lines[i].strip().startswith("${"): lines[i] = None lines[i - 1] = None - lines = '\n'.join(filter(lambda x: x is not None, lines)) + lines = '\n'.join([x for x in lines if x is not None]) # Write out the file with variables replaced. fd = open(dest, 'w') @@ -237,7 +237,7 @@ class MacTool(object): dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo') fp = open(dest, 'w') - fp.write('%s%s' % (package_type, signature_code)) + fp.write('{}{}'.format(package_type, signature_code)) fp.close() def ExecFlock(self, lockfile, *cmd_list): @@ -266,7 +266,7 @@ class MacTool(object): _, err = libtoolout.communicate() for line in err.splitlines(): if not libtool_re.match(line) and not libtool_re5.match(line): - print >>sys.stderr, line + print(line, file=sys.stderr) # Unconditionally touch the output .a file on the command line if present # and the command succeeded. A bit hacky. if not libtoolout.returncode: @@ -331,7 +331,7 @@ class MacTool(object): def ExecCompileIosFrameworkHeaderMap(self, out, framework, *all_headers): framework_name = os.path.basename(framework).split('.')[0] - all_headers = map(os.path.abspath, all_headers) + all_headers = list(map(os.path.abspath, all_headers)) filelist = {} for header in all_headers: filename = os.path.basename(header) @@ -381,7 +381,7 @@ class MacTool(object): ]) if keys: keys = json.loads(keys) - for key, value in keys.iteritems(): + for key, value in keys.items(): arg_name = '--' + key if isinstance(value, bool): if value: @@ -395,7 +395,7 @@ class MacTool(object): command_line.append(str(value)) # Note: actool crashes if inputs path are relative, so use os.path.abspath # to get absolute path name for inputs. - command_line.extend(map(os.path.abspath, inputs)) + command_line.extend(list(map(os.path.abspath, inputs))) subprocess.check_call(command_line) def ExecMergeInfoPlist(self, output, *inputs): @@ -476,8 +476,8 @@ class MacTool(object): profiles_dir = os.path.join( os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles') if not os.path.isdir(profiles_dir): - print >>sys.stderr, ( - 'cannot find mobile provisioning for %s' % bundle_identifier) + print(( + 'cannot find mobile provisioning for %s' % bundle_identifier), file=sys.stderr) sys.exit(1) provisioning_profiles = None if profile: @@ -493,13 +493,13 @@ class MacTool(object): app_id_pattern = profile_data.get( 'Entitlements', {}).get('application-identifier', '') for team_identifier in profile_data.get('TeamIdentifier', []): - app_id = '%s.%s' % (team_identifier, bundle_identifier) + app_id = '{}.{}'.format(team_identifier, bundle_identifier) if fnmatch.fnmatch(app_id, app_id_pattern): valid_provisioning_profiles[app_id_pattern] = ( profile_path, profile_data, team_identifier) if not valid_provisioning_profiles: - print >>sys.stderr, ( - 'cannot find mobile provisioning for %s' % bundle_identifier) + print(( + 'cannot find mobile provisioning for %s' % bundle_identifier), file=sys.stderr) sys.exit(1) # If the user has multiple provisioning profiles installed that can be # used for ${bundle_identifier}, pick the most specific one (ie. the @@ -523,7 +523,7 @@ class MacTool(object): def _MergePlist(self, merged_plist, plist): """Merge |plist| into |merged_plist|.""" - for key, value in plist.iteritems(): + for key, value in plist.items(): if isinstance(value, dict): merged_value = merged_plist.get(key, {}) if isinstance(merged_value, dict): @@ -633,7 +633,7 @@ class MacTool(object): the key was not found. """ if isinstance(data, str): - for key, value in substitutions.iteritems(): + for key, value in substitutions.items(): data = data.replace('$(%s)' % key, value) return data if isinstance(data, list): @@ -663,7 +663,7 @@ def WriteHmap(output_name, filelist): count = len(filelist) capacity = NextGreaterPowerOf2(count) strings_offset = 24 + (12 * capacity) - max_value_length = len(max(filelist.items(), key=lambda (k,v):len(v))[1]) + max_value_length = len(max(list(filelist.items()), key=lambda k_v:len(k_v[1]))[1]) out = open(output_name, "wb") out.write(struct.pack(' - + -''' % (execution_level_map[execution_level], ui_access) +'''.format(execution_level_map[execution_level], ui_access) else: inner = '' @@ -806,7 +805,7 @@ class MsvsSettings(object): bash_cmd = ' '.join(args) cmd = ( 'call "%s\\setup_env.bat" && set CYGWIN=nontsec && ' % cygwin_dir + - 'bash -c "%s ; %s"' % (cd, bash_cmd)) + 'bash -c "{} ; {}"'.format(cd, bash_cmd)) return cmd def IsRuleRunUnderCygwin(self, rule): @@ -873,7 +872,7 @@ def _LanguageMatchesForPch(source_ext, pch_source_ext): (source_ext in cc_exts and pch_source_ext in cc_exts)) -class PrecompiledHeader(object): +class PrecompiledHeader: """Helper to generate dependencies and build rules to handle generation of precompiled headers. Interface matches the GCH handler in xcode_emulation.py. """ @@ -917,10 +916,10 @@ class PrecompiledHeader(object): if input == self.pch_source: pch_output = ['/Yc' + self._PchHeader()] if command == 'cxx': - return ([('cflags_cc', map(expand_special, cflags_cc + pch_output))], + return ([('cflags_cc', list(map(expand_special, cflags_cc + pch_output)))], self.output_obj, []) elif command == 'cc': - return ([('cflags_c', map(expand_special, cflags_c + pch_output))], + return ([('cflags_c', list(map(expand_special, cflags_c + pch_output)))], self.output_obj, []) return [], output, implicit @@ -942,7 +941,7 @@ def ExpandMacros(string, expansions): """Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv for the canonical way to retrieve a suitable dict.""" if '$' in string: - for old, new in expansions.iteritems(): + for old, new in expansions.items(): assert '$(' not in new, new string = string.replace(old, new) return string @@ -990,7 +989,7 @@ def _FormatAsEnvironmentBlock(envvar_dict): CreateProcess documentation for more details.""" block = '' nul = '\0' - for key, value in envvar_dict.iteritems(): + for key, value in envvar_dict.items(): block += key + '=' + value + nul block += nul return block @@ -1065,9 +1064,9 @@ def VerifyMissingSources(sources, build_dir, generator_flags, gyp_to_ninja): VS, and we want this check to match for people/bots that build using ninja, so they're not surprised when the VS build fails.""" if int(generator_flags.get('msvs_error_on_missing_sources', 0)): - no_specials = filter(lambda x: '$' not in x, sources) + no_specials = [x for x in sources if '$' not in x] relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials] - missing = filter(lambda x: not os.path.exists(x), relative) + missing = [x for x in relative if not os.path.exists(x)] if missing: # They'll look like out\Release\..\..\stuff\things.cc, so normalize the # path for a slightly less crazy looking output. diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/ninja_syntax.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/ninja_syntax.py index d2948f06c0..e260398af8 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/ninja_syntax.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/ninja_syntax.py @@ -15,7 +15,7 @@ import re def escape_path(word): return word.replace('$ ','$$ ').replace(' ','$ ').replace(':', '$:') -class Writer(object): +class Writer: def __init__(self, output, width=78): self.output = output self.width = width @@ -31,8 +31,8 @@ class Writer(object): if value is None: return if isinstance(value, list): - value = ' '.join(filter(None, value)) # Filter out empty strings. - self._line('%s = %s' % (key, value), indent) + value = ' '.join([_f for _f in value if _f]) # Filter out empty strings. + self._line('{} = {}'.format(key, value), indent) def pool(self, name, depth): self._line('pool %s' % name) @@ -68,15 +68,15 @@ class Writer(object): all_inputs = list(map(escape_path, all_inputs)) if implicit: - implicit = map(escape_path, self._as_list(implicit)) + implicit = list(map(escape_path, self._as_list(implicit))) all_inputs.append('|') all_inputs.extend(implicit) if order_only: - order_only = map(escape_path, self._as_list(order_only)) + order_only = list(map(escape_path, self._as_list(order_only))) all_inputs.append('||') all_inputs.extend(order_only) - self._line('build %s: %s' % (' '.join(out_outputs), + self._line('build {}: {}'.format(' '.join(out_outputs), ' '.join([rule] + all_inputs))) if variables: diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/ordered_dict.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/ordered_dict.py index a1e89f9199..a1be68ec57 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/ordered_dict.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/ordered_dict.py @@ -30,9 +30,9 @@ # Passes Python2.7's test suite and incorporates all the latest updates. try: - from thread import get_ident as _get_ident + from _thread import get_ident as _get_ident except ImportError: - from dummy_thread import get_ident as _get_ident + from _thread import get_ident as _get_ident try: from _abcoll import KeysView, ValuesView, ItemsView @@ -106,7 +106,7 @@ class OrderedDict(dict): def clear(self): 'od.clear() -> None. Remove all items from od.' try: - for node in self.__map.itervalues(): + for node in self.__map.values(): del node[:] root = self.__root root[:] = [root, root, None] @@ -231,8 +231,8 @@ class OrderedDict(dict): _repr_running[call_key] = 1 try: if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, self.items()) + return '{}()'.format(self.__class__.__name__) + return '{}({!r})'.format(self.__class__.__name__, list(self.items())) finally: del _repr_running[call_key] @@ -267,7 +267,7 @@ class OrderedDict(dict): ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return len(self)==len(other) and list(self.items()) == list(other.items()) return dict.__eq__(self, other) def __ne__(self, other): diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/simple_copy.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/simple_copy.py index 74c98c5a79..571baa4193 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/simple_copy.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/simple_copy.py @@ -28,8 +28,8 @@ _deepcopy_dispatch = d = {} def _deepcopy_atomic(x): return x -for x in (type(None), int, long, float, - bool, str, unicode, type): +for x in (type(None), int, int, float, + bool, str, str, type): d[x] = _deepcopy_atomic def _deepcopy_list(x): @@ -38,7 +38,7 @@ d[list] = _deepcopy_list def _deepcopy_dict(x): y = {} - for key, value in x.iteritems(): + for key, value in x.items(): y[deepcopy(key)] = deepcopy(value) return y d[dict] = _deepcopy_dict diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py index 1c843a0b6c..a5fb64e86a 100755 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py @@ -30,7 +30,7 @@ def main(args): sys.exit(exit_code) -class WinTool(object): +class WinTool: """This class performs all the Windows tooling steps. The methods can either be executed directly, or dispatched from an argument list.""" @@ -134,7 +134,7 @@ class WinTool(object): if (not line.startswith(' Creating library ') and not line.startswith('Generating code') and not line.startswith('Finished generating code')): - print line + print(line) return link.returncode def ExecLinkWithManifests(self, arch, embed_manifest, out, ldcmd, resname, @@ -223,7 +223,7 @@ class WinTool(object): out, _ = popen.communicate() for line in out.splitlines(): if line and 'manifest authoring warning 81010002' not in line: - print line + print(line) return popen.returncode def ExecManifestToRc(self, arch, *args): @@ -232,7 +232,7 @@ class WinTool(object): and resource name which can be "1" (for executables) or "2" (for DLLs).""" manifest_path, resource_path, resource_name = args with open(resource_path, 'wb') as output: - output.write('#include \n%s RT_MANIFEST "%s"' % ( + output.write('#include \n{} RT_MANIFEST "{}"'.format( resource_name, os.path.abspath(manifest_path).replace('\\', '/'))) @@ -259,11 +259,11 @@ class WinTool(object): # objidl.idl lines = out.splitlines() prefixes = ('Processing ', '64 bit Processing ') - processing = set(os.path.basename(x) - for x in lines if x.startswith(prefixes)) + processing = {os.path.basename(x) + for x in lines if x.startswith(prefixes)} for line in lines: if not line.startswith(prefixes) and line not in processing: - print line + print(line) return popen.returncode def ExecAsmWrapper(self, arch, *args): @@ -277,7 +277,7 @@ class WinTool(object): not line.startswith('Microsoft (R) Macro Assembler') and not line.startswith(' Assembling: ') and line): - print line + print(line) return popen.returncode def ExecRcWrapper(self, arch, *args): @@ -291,7 +291,7 @@ class WinTool(object): if (not line.startswith('Microsoft (R) Windows (R) Resource Compiler') and not line.startswith('Copyright (C) Microsoft Corporation') and line): - print line + print(line) return popen.returncode def ExecActionWrapper(self, arch, rspfile, *dir): @@ -300,7 +300,7 @@ class WinTool(object): env = self._GetEnv(arch) # TODO(scottmg): This is a temporary hack to get some specific variables # through to actions that are set after gyp-time. http://crbug.com/333738. - for k, v in os.environ.iteritems(): + for k, v in os.environ.items(): if k not in env: env[k] = v args = open(rspfile).read() diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py index dba8e7699e..b99d5eac27 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py @@ -36,7 +36,7 @@ def XcodeArchsVariableMapping(archs, archs_including_64_bit=None): mapping['$(ARCHS_STANDARD_INCLUDING_64_BIT)'] = archs_including_64_bit return mapping -class XcodeArchsDefault(object): +class XcodeArchsDefault: """A class to resolve ARCHS variable from xcode_settings, resolving Xcode macros and implementing filtering by VALID_ARCHS. The expansion of macros depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and @@ -73,7 +73,7 @@ class XcodeArchsDefault(object): if arch not in expanded_archs: expanded_archs.append(arch) except KeyError as e: - print 'Warning: Ignoring unsupported variable "%s".' % variable + print('Warning: Ignoring unsupported variable "%s".' % variable) elif arch not in expanded_archs: expanded_archs.append(arch) return expanded_archs @@ -141,7 +141,7 @@ def GetXcodeArchsDefault(): return XCODE_ARCHS_DEFAULT_CACHE -class XcodeSettings(object): +class XcodeSettings: """A class that understands the gyp 'xcode_settings' object.""" # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached @@ -171,7 +171,7 @@ class XcodeSettings(object): # the same for all configs are implicitly per-target settings. self.xcode_settings = {} configs = spec['configurations'] - for configname, config in configs.iteritems(): + for configname, config in configs.items(): self.xcode_settings[configname] = config.get('xcode_settings', {}) self._ConvertConditionalKeys(configname) if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET', @@ -197,8 +197,8 @@ class XcodeSettings(object): new_key = key.split("[")[0] settings[new_key] = settings[key] else: - print 'Warning: Conditional keys not implemented, ignoring:', \ - ' '.join(conditional_keys) + print('Warning: Conditional keys not implemented, ignoring:', \ + ' '.join(conditional_keys)) del settings[key] def _Settings(self): @@ -216,7 +216,7 @@ class XcodeSettings(object): def _WarnUnimplemented(self, test_key): if test_key in self._Settings(): - print 'Warning: Ignoring not yet implemented key "%s".' % test_key + print('Warning: Ignoring not yet implemented key "%s".' % test_key) def IsBinaryOutputFormat(self, configname): default = "binary" if self.isIOS else "xml" @@ -271,7 +271,7 @@ class XcodeSettings(object): else: return '.' + self.spec.get('product_extension', 'app') else: - assert False, "Don't know extension for '%s', target '%s'" % ( + assert False, "Don't know extension for '{}', target '{}'".format( self.spec['type'], self.spec['target_name']) def GetProductName(self): @@ -963,7 +963,7 @@ class XcodeSettings(object): result = dict(self.xcode_settings[configname]) first_pass = False else: - for key, value in self.xcode_settings[configname].iteritems(): + for key, value in self.xcode_settings[configname].items(): if key not in result: continue elif result[key] != value: @@ -1023,7 +1023,7 @@ class XcodeSettings(object): if not quiet: result.append('echo STRIP\\(%s\\)' % self.spec['target_name']) - result.append('strip %s %s' % (strip_flags, output_binary)) + result.append('strip {} {}'.format(strip_flags, output_binary)) self.configname = None return result @@ -1042,7 +1042,7 @@ class XcodeSettings(object): self.spec['type'] != 'static_library'): if not quiet: result.append('echo DSYMUTIL\\(%s\\)' % self.spec['target_name']) - result.append('dsymutil %s -o %s' % (output_binary, output + '.dSYM')) + result.append('dsymutil {} -o {}'.format(output_binary, output + '.dSYM')) self.configname = None return result @@ -1074,7 +1074,7 @@ class XcodeSettings(object): source = os.path.join("${BUILT_PRODUCTS_DIR}", product_name) test_host = os.path.dirname(settings.get('TEST_HOST')); xctest_destination = os.path.join(test_host, 'PlugIns', product_name) - postbuilds.extend(['ditto %s %s' % (source, xctest_destination)]) + postbuilds.extend(['ditto {} {}'.format(source, xctest_destination)]) key = self._GetIOSCodeSignIdentityKey(settings) if not key: @@ -1084,8 +1084,8 @@ class XcodeSettings(object): unimpl = ['OTHER_CODE_SIGN_FLAGS'] unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) if unimpl: - print 'Warning: Some codesign keys not implemented, ignoring: %s' % ( - ', '.join(sorted(unimpl))) + print('Warning: Some codesign keys not implemented, ignoring: %s' % ( + ', '.join(sorted(unimpl)))) if self._IsXCTest(): # For device xctests, Xcode copies two extra frameworks into $TEST_HOST. @@ -1098,10 +1098,10 @@ class XcodeSettings(object): for framework in frameworks: source = os.path.join(platform_root, framework) destination = os.path.join(frameworks_dir, os.path.basename(framework)) - postbuilds.extend(['ditto %s %s' % (source, destination)]) + postbuilds.extend(['ditto {} {}'.format(source, destination)]) # Then re-sign everything with 'preserve=True' - postbuilds.extend(['%s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + postbuilds.extend(['{} code-sign-bundle "{}" "{}" "{}" "{}" {}'.format( os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, settings.get('CODE_SIGN_ENTITLEMENTS', ''), settings.get('PROVISIONING_PROFILE', ''), destination, True) @@ -1109,13 +1109,13 @@ class XcodeSettings(object): plugin_dir = os.path.join(test_host, 'PlugIns') targets = [os.path.join(plugin_dir, product_name), test_host] for target in targets: - postbuilds.extend(['%s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + postbuilds.extend(['{} code-sign-bundle "{}" "{}" "{}" "{}" {}'.format( os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, settings.get('CODE_SIGN_ENTITLEMENTS', ''), settings.get('PROVISIONING_PROFILE', ''), target, True) ]) - postbuilds.extend(['%s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + postbuilds.extend(['{} code-sign-bundle "{}" "{}" "{}" "{}" {}'.format( os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, settings.get('CODE_SIGN_ENTITLEMENTS', ''), settings.get('PROVISIONING_PROFILE', ''), @@ -1272,7 +1272,7 @@ class XcodeSettings(object): return '' -class MacPrefixHeader(object): +class MacPrefixHeader: """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. This feature consists of several pieces: @@ -1725,7 +1725,7 @@ def _TopologicallySortedEnvVarKeys(env): # definition contains all variables it references in a single string. # We can then reverse the result of the topological sort at the end. # Since: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) - matches = set([v for v in regex.findall(env[node]) if v in env]) + matches = {v for v in regex.findall(env[node]) if v in env} for dependee in matches: assert '${' not in dependee, 'Nested variables not supported: ' + dependee return matches @@ -1734,10 +1734,10 @@ def _TopologicallySortedEnvVarKeys(env): # Topologically sort, and then reverse, because we used an edge definition # that's inverted from the expected result of this function (see comment # above). - order = gyp.common.TopologicallySorted(env.keys(), GetEdges) + order = gyp.common.TopologicallySorted(list(env.keys()), GetEdges) order.reverse() return order - except gyp.common.CycleError, e: + except gyp.common.CycleError as e: raise GypError( 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) @@ -1755,7 +1755,7 @@ def GetSpecPostbuildCommands(spec, quiet=False): postbuilds = [] for postbuild in spec.get('postbuilds', []): if not quiet: - postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( + postbuilds.append('echo POSTBUILD\\({}\\) {}'.format( spec['target_name'], postbuild['postbuild_name'])) postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) return postbuilds @@ -1774,10 +1774,10 @@ def _HasIOSTarget(targets): def _AddIOSDeviceConfigurations(targets): """Clone all targets and append -iphoneos to the name. Configure these targets to build for iOS devices and use correct architectures for those builds.""" - for target_dict in targets.itervalues(): + for target_dict in targets.values(): toolset = target_dict['toolset'] configs = target_dict['configurations'] - for config_name, simulator_config_dict in dict(configs).iteritems(): + for config_name, simulator_config_dict in dict(configs).items(): iphoneos_config_dict = copy.deepcopy(simulator_config_dict) configs[config_name + '-iphoneos'] = iphoneos_config_dict configs[config_name + '-iphonesimulator'] = simulator_config_dict diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_ninja.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_ninja.py index bc76ffff4e..6614247cea 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_ninja.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_ninja.py @@ -28,7 +28,7 @@ def _WriteWorkspace(main_gyp, sources_gyp, params): workspace_path = os.path.join(options.generator_output, workspace_path) try: os.makedirs(workspace_path) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise output_string = '\n' + \ @@ -42,11 +42,11 @@ def _WriteWorkspace(main_gyp, sources_gyp, params): workspace_file = os.path.join(workspace_path, "contents.xcworkspacedata") try: - with open(workspace_file, 'r') as input_file: + with open(workspace_file) as input_file: input_string = input_file.read() if input_string == output_string: return - except IOError: + except OSError: # Ignore errors if the file doesn't exist. pass @@ -85,7 +85,7 @@ def _TargetFromSpec(old_spec, params): "%s/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" % ninja_toplevel if 'configurations' in old_spec: - for config in old_spec['configurations'].iterkeys(): + for config in old_spec['configurations'].keys(): old_xcode_settings = \ old_spec['configurations'][config].get('xcode_settings', {}) if 'IPHONEOS_DEPLOYMENT_TARGET' in old_xcode_settings: @@ -167,7 +167,7 @@ def CreateWrapper(target_list, target_dicts, data, params): params: Dict of global options for gyp. """ orig_gyp = params['build_files'][0] - for gyp_name, gyp_dict in data.iteritems(): + for gyp_name, gyp_dict in data.items(): if gyp_name == orig_gyp: depth = gyp_dict['_DEPTH'] @@ -206,7 +206,7 @@ def CreateWrapper(target_list, target_dicts, data, params): if IsValidTargetForWrapper(target_extras, executable_target_pattern, spec): # Add to new_target_list. target_name = spec.get('target_name') - new_target_name = '%s:%s#target' % (main_gyp, target_name) + new_target_name = '{}:{}#target'.format(main_gyp, target_name) new_target_list.append(new_target_name) # Add to new_target_dicts. @@ -238,7 +238,7 @@ def CreateWrapper(target_list, target_dicts, data, params): not generator_flags.get('xcode_ninja_list_excluded_files', True) sources = [] - for target, target_dict in target_dicts.iteritems(): + for target, target_dict in target_dicts.items(): base = os.path.dirname(target) files = target_dict.get('sources', []) + \ target_dict.get('mac_bundle_resources', []) @@ -268,7 +268,7 @@ def CreateWrapper(target_list, target_dicts, data, params): sources_gyp = \ os.path.join(os.path.dirname(main_gyp), sources_target_name + ".gyp") fully_qualified_target_name = \ - '%s:%s#target' % (sources_gyp, sources_target_name) + '{}:{}#target'.format(sources_gyp, sources_target_name) # Add to new_target_list, new_target_dicts and new_data. new_target_list.append(fully_qualified_target_name) diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py index e69235f724..e2235bc5db 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py @@ -198,7 +198,7 @@ def SourceTreeAndPathFromPath(input_path): def ConvertVariablesToShellSyntax(input_string): return re.sub(r'\$\((.*?)\)', '${\\1}', input_string) -class XCObject(object): +class XCObject: """The abstract base of all class types used in Xcode project files. Class variables: @@ -300,8 +300,8 @@ class XCObject(object): try: name = self.Name() except NotImplementedError: - return '<%s at 0x%x>' % (self.__class__.__name__, id(self)) - return '<%s %r at 0x%x>' % (self.__class__.__name__, name, id(self)) + return '<{} at 0x{:x}>'.format(self.__class__.__name__, id(self)) + return '<{} {!r} at 0x{:x}>'.format(self.__class__.__name__, name, id(self)) def Copy(self): """Make a copy of this object. @@ -314,7 +314,7 @@ class XCObject(object): """ that = self.__class__(id=self.id, parent=self.parent) - for key, value in self._properties.iteritems(): + for key, value in self._properties.items(): is_strong = self._schema[key][2] if isinstance(value, XCObject): @@ -324,7 +324,7 @@ class XCObject(object): that._properties[key] = new_value else: that._properties[key] = value - elif isinstance(value, str) or isinstance(value, unicode) or \ + elif isinstance(value, str) or isinstance(value, str) or \ isinstance(value, int): that._properties[key] = value elif isinstance(value, list): @@ -452,7 +452,7 @@ class XCObject(object): digest_int_count = hash.digest_size / 4 digest_ints = struct.unpack('>' + 'I' * digest_int_count, hash.digest()) id_ints = [0, 0, 0] - for index in xrange(0, digest_int_count): + for index in range(0, digest_int_count): id_ints[index % 3] ^= digest_ints[index] self.id = '%08X%08X%08X' % tuple(id_ints) @@ -475,7 +475,7 @@ class XCObject(object): """Returns a list of all of this object's owned (strong) children.""" children = [] - for property, attributes in self._schema.iteritems(): + for property, attributes in self._schema.items(): (is_list, property_type, is_strong) = attributes[0:3] if is_strong and property in self._properties: if not is_list: @@ -603,7 +603,7 @@ class XCObject(object): comment = value.Comment() elif isinstance(value, str): printable += self._EncodeString(value) - elif isinstance(value, unicode): + elif isinstance(value, str): printable += self._EncodeString(value.encode('utf-8')) elif isinstance(value, int): printable += str(value) @@ -622,7 +622,7 @@ class XCObject(object): printable += end_tabs + ')' elif isinstance(value, dict): printable = '{' + sep - for item_key, item_value in sorted(value.iteritems()): + for item_key, item_value in sorted(value.items()): printable += element_tabs + \ self._XCPrintableValue(tabs + 1, item_key, flatten_list) + ' = ' + \ self._XCPrintableValue(tabs + 1, item_value, flatten_list) + ';' + \ @@ -691,7 +691,7 @@ class XCObject(object): printable_value[0] == '"' and printable_value[-1] == '"': printable_value = printable_value[1:-1] printable += printable_key + ' = ' + printable_value + ';' + after_kv - except TypeError, e: + except TypeError as e: gyp.common.ExceptionAppend(e, 'while printing key "%s"' % key) raise @@ -730,7 +730,7 @@ class XCObject(object): self._XCKVPrint(file, 3, 'isa', self.__class__.__name__) # The remaining elements of an object dictionary are sorted alphabetically. - for property, value in sorted(self._properties.iteritems()): + for property, value in sorted(self._properties.items()): self._XCKVPrint(file, 3, property, value) # End the object. @@ -752,7 +752,7 @@ class XCObject(object): if properties is None: return - for property, value in properties.iteritems(): + for property, value in properties.items(): # Make sure the property is in the schema. if not property in self._schema: raise KeyError(property + ' not in ' + self.__class__.__name__) @@ -766,7 +766,7 @@ class XCObject(object): ' must be list, not ' + value.__class__.__name__) for item in value: if not isinstance(item, property_type) and \ - not (item.__class__ == unicode and property_type == str): + not (item.__class__ == str and property_type == str): # Accept unicode where str is specified. str is treated as # UTF-8-encoded. raise TypeError( @@ -774,7 +774,7 @@ class XCObject(object): ' must be ' + property_type.__name__ + ', not ' + \ item.__class__.__name__) elif not isinstance(value, property_type) and \ - not (value.__class__ == unicode and property_type == str): + not (value.__class__ == str and property_type == str): # Accept unicode where str is specified. str is treated as # UTF-8-encoded. raise TypeError( @@ -788,7 +788,7 @@ class XCObject(object): self._properties[property] = value.Copy() else: self._properties[property] = value - elif isinstance(value, str) or isinstance(value, unicode) or \ + elif isinstance(value, str) or isinstance(value, str) or \ isinstance(value, int): self._properties[property] = value elif isinstance(value, list): @@ -865,7 +865,7 @@ class XCObject(object): # TODO(mark): A stronger verification mechanism is needed. Some # subclasses need to perform validation beyond what the schema can enforce. - for property, attributes in self._schema.iteritems(): + for property, attributes in self._schema.items(): (is_list, property_type, is_strong, is_required) = attributes[0:4] if is_required and not property in self._properties: raise KeyError(self.__class__.__name__ + ' requires ' + property) @@ -875,7 +875,7 @@ class XCObject(object): overwrite properties that have already been set.""" defaults = {} - for property, attributes in self._schema.iteritems(): + for property, attributes in self._schema.items(): (is_list, property_type, is_strong, is_required) = attributes[0:4] if is_required and len(attributes) >= 5 and \ not property in self._properties: @@ -1426,7 +1426,7 @@ class XCFileLikeElement(XCHierarchicalElement): xche = self while xche != None and isinstance(xche, XCHierarchicalElement): xche_hashables = xche.Hashables() - for index in xrange(0, len(xche_hashables)): + for index in range(0, len(xche_hashables)): hashables.insert(index, xche_hashables[index]) xche = xche.parent return hashables @@ -2126,8 +2126,8 @@ class PBXContainerItemProxy(XCObject): def __repr__(self): props = self._properties - name = '%s.gyp:%s' % (props['containerPortal'].Name(), props['remoteInfo']) - return '<%s %r at 0x%x>' % (self.__class__.__name__, name, id(self)) + name = '{}.gyp:{}'.format(props['containerPortal'].Name(), props['remoteInfo']) + return '<{} {!r} at 0x{:x}>'.format(self.__class__.__name__, name, id(self)) def Name(self): # Admittedly not the best name, but it's what Xcode uses. @@ -2162,7 +2162,7 @@ class PBXTargetDependency(XCObject): def __repr__(self): name = self._properties.get('name') or self._properties['target'].Name() - return '<%s %r at 0x%x>' % (self.__class__.__name__, name, id(self)) + return '<{} {!r} at 0x{:x}>'.format(self.__class__.__name__, name, id(self)) def Name(self): # Admittedly not the best name, but it's what Xcode uses. @@ -2468,7 +2468,7 @@ class PBXNativeTarget(XCTarget): # The headers phase should come before the resources, sources, and # frameworks phases, if any. insert_at = len(self._properties['buildPhases']) - for index in xrange(0, len(self._properties['buildPhases'])): + for index in range(0, len(self._properties['buildPhases'])): phase = self._properties['buildPhases'][index] if isinstance(phase, PBXResourcesBuildPhase) or \ isinstance(phase, PBXSourcesBuildPhase) or \ @@ -2489,7 +2489,7 @@ class PBXNativeTarget(XCTarget): # The resources phase should come before the sources and frameworks # phases, if any. insert_at = len(self._properties['buildPhases']) - for index in xrange(0, len(self._properties['buildPhases'])): + for index in range(0, len(self._properties['buildPhases'])): phase = self._properties['buildPhases'][index] if isinstance(phase, PBXSourcesBuildPhase) or \ isinstance(phase, PBXFrameworksBuildPhase): @@ -2911,7 +2911,7 @@ class PBXProject(XCContainerPortal): # determine the sort order. return cmp(x_index, y_index) - for other_pbxproject, ref_dict in self._other_pbxprojects.iteritems(): + for other_pbxproject, ref_dict in self._other_pbxprojects.items(): # Build up a list of products in the remote project file, ordered the # same as the targets that produce them. remote_products = [] @@ -2956,7 +2956,7 @@ class XCProjectFile(XCObject): self._XCPrint(file, 0, '{ ') else: self._XCPrint(file, 0, '{\n') - for property, value in sorted(self._properties.iteritems(), + for property, value in sorted(self._properties.items(), cmp=lambda x, y: cmp(x, y)): if property == 'objects': self._PrintObjects(file) diff --git a/media/webrtc/trunk/tools/gyp/pylib/gyp/xml_fix.py b/media/webrtc/trunk/tools/gyp/pylib/gyp/xml_fix.py index 5de848158d..08c2073639 100644 --- a/media/webrtc/trunk/tools/gyp/pylib/gyp/xml_fix.py +++ b/media/webrtc/trunk/tools/gyp/pylib/gyp/xml_fix.py @@ -32,7 +32,7 @@ def _Replacement_writexml(self, writer, indent="", addindent="", newl=""): writer.write(indent+"<" + self.tagName) attrs = self._get_attributes() - a_names = attrs.keys() + a_names = list(attrs.keys()) a_names.sort() for a_name in a_names: @@ -43,12 +43,12 @@ def _Replacement_writexml(self, writer, indent="", addindent="", newl=""): writer.write(">%s" % newl) for node in self.childNodes: node.writexml(writer, indent + addindent, addindent, newl) - writer.write("%s%s" % (indent, self.tagName, newl)) + writer.write("{}{}".format(indent, self.tagName, newl)) else: writer.write("/>%s" % newl) -class XmlFix(object): +class XmlFix: """Object to manage temporary patching of xml.dom.minidom.""" def __init__(self): diff --git a/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs-with-dependencies/gyptest-action.py b/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs-with-dependencies/gyptest-action.py index ebc7f4fd94..fd2870e73b 100755 --- a/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs-with-dependencies/gyptest-action.py +++ b/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs-with-dependencies/gyptest-action.py @@ -10,13 +10,14 @@ Verifies actions with multiple outputs & dependncies will correctly rebuild. This is a regression test for crrev.com/1177163002. """ +from __future__ import print_function import TestGyp import os import sys import time if sys.platform in ('darwin', 'win32'): - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp() diff --git a/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs/gyptest-multiple-outputs.py b/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs/gyptest-multiple-outputs.py index 72a7040a01..d552d36594 100755 --- a/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs/gyptest-multiple-outputs.py +++ b/media/webrtc/trunk/tools/gyp/test/actions-multiple-outputs/gyptest-multiple-outputs.py @@ -8,12 +8,13 @@ Verifies actions with multiple outputs will correctly rebuild. """ +from __future__ import print_function import TestGyp import os import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp() diff --git a/media/webrtc/trunk/tools/gyp/test/actions-multiple/src/filter.py b/media/webrtc/trunk/tools/gyp/test/actions-multiple/src/filter.py index f61a5fa59a..36a9dc7be3 100755 --- a/media/webrtc/trunk/tools/gyp/test/actions-multiple/src/filter.py +++ b/media/webrtc/trunk/tools/gyp/test/actions-multiple/src/filter.py @@ -6,7 +6,7 @@ import sys -data = open(sys.argv[3], 'r').read() +data = open(sys.argv[3]).read() fh = open(sys.argv[4], 'w') fh.write(data.replace(sys.argv[1], sys.argv[2])) fh.close() diff --git a/media/webrtc/trunk/tools/gyp/test/analyzer/gyptest-analyzer.py b/media/webrtc/trunk/tools/gyp/test/analyzer/gyptest-analyzer.py index 72de21813c..5f2f1bef4d 100644 --- a/media/webrtc/trunk/tools/gyp/test/analyzer/gyptest-analyzer.py +++ b/media/webrtc/trunk/tools/gyp/test/analyzer/gyptest-analyzer.py @@ -32,7 +32,7 @@ def _CreateBogusConfigFile(): def _ReadOutputFileContents(): - f = open('analyzer_output', 'r') + f = open('analyzer_output') result = json.load(f) f.close() return result @@ -75,57 +75,57 @@ def EnsureContains(matched=False, compile_targets=set(), test_targets=set()): """Verifies output contains |compile_targets|.""" result = _ReadOutputFileContents() if 'error' in result: - print 'unexpected error', result.get('error') + print('unexpected error', result.get('error')) test.fail_test() if 'invalid_targets' in result: - print 'unexpected invalid_targets', result.get('invalid_targets') + print('unexpected invalid_targets', result.get('invalid_targets')) test.fail_test() actual_compile_targets = set(result['compile_targets']) if actual_compile_targets != compile_targets: - print 'actual compile_targets:', actual_compile_targets, \ - '\nexpected compile_targets:', compile_targets + print('actual compile_targets:', actual_compile_targets, \ + '\nexpected compile_targets:', compile_targets) test.fail_test() actual_test_targets = set(result['test_targets']) if actual_test_targets != test_targets: - print 'actual test_targets:', actual_test_targets, \ - '\nexpected test_targets:', test_targets + print('actual test_targets:', actual_test_targets, \ + '\nexpected test_targets:', test_targets) test.fail_test() if matched and result['status'] != found: - print 'expected', found, 'got', result['status'] + print('expected', found, 'got', result['status']) test.fail_test() elif not matched and result['status'] != not_found: - print 'expected', not_found, 'got', result['status'] + print('expected', not_found, 'got', result['status']) test.fail_test() def EnsureMatchedAll(compile_targets, test_targets=set()): result = _ReadOutputFileContents() if 'error' in result: - print 'unexpected error', result.get('error') + print('unexpected error', result.get('error')) test.fail_test() if 'invalid_targets' in result: - print 'unexpected invalid_targets', result.get('invalid_targets') + print('unexpected invalid_targets', result.get('invalid_targets')) test.fail_test() if result['status'] != found_all: - print 'expected', found_all, 'got', result['status'] + print('expected', found_all, 'got', result['status']) test.fail_test() actual_compile_targets = set(result['compile_targets']) if actual_compile_targets != compile_targets: - print ('actual compile_targets:', actual_compile_targets, - '\nexpected compile_targets:', compile_targets) + print(('actual compile_targets:', actual_compile_targets, + '\nexpected compile_targets:', compile_targets)) test.fail_test() actual_test_targets = set(result['test_targets']) if actual_test_targets != test_targets: - print ('actual test_targets:', actual_test_targets, - '\nexpected test_targets:', test_targets) + print(('actual test_targets:', actual_test_targets, + '\nexpected test_targets:', test_targets)) test.fail_test() @@ -133,15 +133,15 @@ def EnsureError(expected_error_string): """Verifies output contains the error string.""" result = _ReadOutputFileContents() if result.get('error', '').find(expected_error_string) == -1: - print 'actual error:', result.get('error', ''), '\nexpected error:', \ - expected_error_string + print('actual error:', result.get('error', ''), '\nexpected error:', \ + expected_error_string) test.fail_test() def EnsureStdoutContains(expected_error_string): if test.stdout().find(expected_error_string) == -1: - print 'actual stdout:', test.stdout(), '\nexpected stdout:', \ - expected_error_string + print('actual stdout:', test.stdout(), '\nexpected stdout:', \ + expected_error_string) test.fail_test() @@ -150,8 +150,8 @@ def EnsureInvalidTargets(expected_invalid_targets): result = _ReadOutputFileContents() actual_invalid_targets = set(result['invalid_targets']) if actual_invalid_targets != expected_invalid_targets: - print 'actual invalid_targets:', actual_invalid_targets, \ - '\nexpected :', expected_invalid_targets + print('actual invalid_targets:', actual_invalid_targets, \ + '\nexpected :', expected_invalid_targets) test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/arflags/gyptest-arflags.py b/media/webrtc/trunk/tools/gyp/test/arflags/gyptest-arflags.py index a5cbcac77d..36248fd63b 100644 --- a/media/webrtc/trunk/tools/gyp/test/arflags/gyptest-arflags.py +++ b/media/webrtc/trunk/tools/gyp/test/arflags/gyptest-arflags.py @@ -13,7 +13,7 @@ import sys import TestGyp if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/compiler-override/gyptest-compiler-global-settings.py b/media/webrtc/trunk/tools/gyp/test/compiler-override/gyptest-compiler-global-settings.py index d58fc7c2f9..500c7a56f7 100755 --- a/media/webrtc/trunk/tools/gyp/test/compiler-override/gyptest-compiler-global-settings.py +++ b/media/webrtc/trunk/tools/gyp/test/compiler-override/gyptest-compiler-global-settings.py @@ -66,7 +66,7 @@ test.must_contain_all_lines(test.stdout(), ['my_cc.py', 'my_cxx.py', 'BAR']) # Check that CC_host overrides make_global_settings old_env = dict(os.environ) -os.environ['CC_host'] = '%s %s/my_cc.py SECRET' % (replacements['PYTHON'], +os.environ['CC_host'] = '{} {}/my_cc.py SECRET'.format(replacements['PYTHON'], replacements['PWD']) test.run_gyp(gypfile) os.environ.clear() diff --git a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cc.py b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cc.py index e2f0bdd51c..b4d9e32b8b 100755 --- a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cc.py +++ b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cc.py @@ -3,4 +3,4 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) diff --git a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cxx.py b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cxx.py index e2f0bdd51c..b4d9e32b8b 100755 --- a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cxx.py +++ b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_cxx.py @@ -3,4 +3,4 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) diff --git a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_ld.py b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_ld.py index e2f0bdd51c..b4d9e32b8b 100755 --- a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_ld.py +++ b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_ld.py @@ -3,4 +3,4 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) diff --git a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_nm.py b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_nm.py index f0f1efcf73..578d680bc5 100755 --- a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_nm.py +++ b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_nm.py @@ -3,6 +3,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) with open('RAN_MY_NM', 'w') as f: f.write('RAN_MY_NM') diff --git a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_readelf.py b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_readelf.py index 40e303cd76..6ec7c9ea22 100755 --- a/media/webrtc/trunk/tools/gyp/test/compiler-override/my_readelf.py +++ b/media/webrtc/trunk/tools/gyp/test/compiler-override/my_readelf.py @@ -3,6 +3,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) with open('RAN_MY_READELF', 'w') as f: f.write('RAN_MY_READELF') diff --git a/media/webrtc/trunk/tools/gyp/test/configurations/inheritance/gyptest-duplicates.py b/media/webrtc/trunk/tools/gyp/test/configurations/inheritance/gyptest-duplicates.py index 46687b4549..ebf5a5791f 100755 --- a/media/webrtc/trunk/tools/gyp/test/configurations/inheritance/gyptest-duplicates.py +++ b/media/webrtc/trunk/tools/gyp/test/configurations/inheritance/gyptest-duplicates.py @@ -27,7 +27,7 @@ contents = test.read('duplicates.gypd').replace( '\r', '').replace('\\\\', '/') expect = test.read('duplicates.gypd.golden').replace('\r', '') if not test.match(contents, expect): - print "Unexpected contents of `duplicates.gypd'" + print("Unexpected contents of `duplicates.gypd'") test.diff(expect, contents, 'duplicates.gypd ') test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/configurations/target_platform/gyptest-target_platform.py b/media/webrtc/trunk/tools/gyp/test/configurations/target_platform/gyptest-target_platform.py index ae4e9e5a2d..9e25864989 100755 --- a/media/webrtc/trunk/tools/gyp/test/configurations/target_platform/gyptest-target_platform.py +++ b/media/webrtc/trunk/tools/gyp/test/configurations/target_platform/gyptest-target_platform.py @@ -15,7 +15,7 @@ import TestCommon def RunX64(exe, stdout): try: test.run_built_executable(exe, stdout=stdout) - except WindowsError, e: + except OSError as e: # Assume the exe is 64-bit if it can't load on 32-bit systems. # Both versions of the error are required because different versions # of python seem to return different errors for invalid exe type. diff --git a/media/webrtc/trunk/tools/gyp/test/copies/gyptest-updir.py b/media/webrtc/trunk/tools/gyp/test/copies/gyptest-updir.py index a34ae70723..19012d6d27 100755 --- a/media/webrtc/trunk/tools/gyp/test/copies/gyptest-updir.py +++ b/media/webrtc/trunk/tools/gyp/test/copies/gyptest-updir.py @@ -14,7 +14,7 @@ import sys import TestGyp if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp() diff --git a/media/webrtc/trunk/tools/gyp/test/determinism/gyptest-solibs.py b/media/webrtc/trunk/tools/gyp/test/determinism/gyptest-solibs.py index de9588db1c..309ce6d9a0 100644 --- a/media/webrtc/trunk/tools/gyp/test/determinism/gyptest-solibs.py +++ b/media/webrtc/trunk/tools/gyp/test/determinism/gyptest-solibs.py @@ -28,7 +28,7 @@ if test.format == 'ninja': if base1 != contents1: test.fail_test() if base2 != contents2: - print base2 + print(base2) test.fail_test() del os.environ["PYTHONHASHSEED"] diff --git a/media/webrtc/trunk/tools/gyp/test/determinism/rule.py b/media/webrtc/trunk/tools/gyp/test/determinism/rule.py index 310a98192c..befec608ff 100644 --- a/media/webrtc/trunk/tools/gyp/test/determinism/rule.py +++ b/media/webrtc/trunk/tools/gyp/test/determinism/rule.py @@ -1,3 +1,5 @@ #!/usr/bin/env python -print 'Hello World' +#!/usr/bin/env python + +print('Hello World') diff --git a/media/webrtc/trunk/tools/gyp/test/escaping/gyptest-colon.py b/media/webrtc/trunk/tools/gyp/test/escaping/gyptest-colon.py index 61a0e245f9..0f4a68a7c7 100644 --- a/media/webrtc/trunk/tools/gyp/test/escaping/gyptest-colon.py +++ b/media/webrtc/trunk/tools/gyp/test/escaping/gyptest-colon.py @@ -9,11 +9,12 @@ Tests that filenames that contain colons are handled correctly. (This is important for absolute paths on Windows.) """ +from __future__ import print_function import os import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/generator-output/gyptest-mac-bundle.py b/media/webrtc/trunk/tools/gyp/test/generator-output/gyptest-mac-bundle.py index 8d19eedbed..38f4f6fce2 100644 --- a/media/webrtc/trunk/tools/gyp/test/generator-output/gyptest-mac-bundle.py +++ b/media/webrtc/trunk/tools/gyp/test/generator-output/gyptest-mac-bundle.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=[]) diff --git a/media/webrtc/trunk/tools/gyp/test/generator-output/rules/copy-file.py b/media/webrtc/trunk/tools/gyp/test/generator-output/rules/copy-file.py index 938c336adb..8e513f6bbe 100755 --- a/media/webrtc/trunk/tools/gyp/test/generator-output/rules/copy-file.py +++ b/media/webrtc/trunk/tools/gyp/test/generator-output/rules/copy-file.py @@ -6,7 +6,7 @@ import sys -contents = open(sys.argv[1], 'r').read() +contents = open(sys.argv[1]).read() open(sys.argv[2], 'wb').write(contents) sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-app-ios.py b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-app-ios.py index f9052549d0..da33c054b9 100755 --- a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-app-ios.py +++ b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-app-ios.py @@ -17,13 +17,13 @@ def CheckFileXMLPropertyList(file): output = subprocess.check_output(['file', file]) # The double space after XML is intentional. if not 'XML document text' in output: - print 'File: Expected XML document text, got %s' % output + print('File: Expected XML document text, got %s' % output) test.fail_test() def CheckFileBinaryPropertyList(file): output = subprocess.check_output(['file', file]) if not 'Apple binary property list' in output: - print 'File: Expected Apple binary property list, got %s' % output + print('File: Expected Apple binary property list, got %s' % output) test.fail_test() if sys.platform == 'darwin': diff --git a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-archs.py b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-archs.py index c653d997ad..daf2e014db 100644 --- a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-archs.py +++ b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-archs.py @@ -48,7 +48,7 @@ if sys.platform == 'darwin': kwds['arguments'].extend(['-arch', archs[0]]) test.set_configuration(configuration) - filename = '%s.app/%s' % (target, target) + filename = '{}.app/{}'.format(target, target) test.build('test-archs.gyp', target, chdir='app-bundle', **kwds) result_file = test.built_file_path(filename, chdir='app-bundle') diff --git a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-extension.py b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-extension.py index c5e76d93ff..ed313ffe01 100755 --- a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-extension.py +++ b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-extension.py @@ -15,12 +15,12 @@ import sys def CheckStrip(p, expected): if expected not in subprocess.check_output(['nm','-gU', p]): - print expected + " shouldn't get stripped out." + print(expected + " shouldn't get stripped out.") test.fail_test() def CheckEntrypoint(p, expected): if expected not in subprocess.check_output(['nm', p]): - print expected + "not found." + print(expected + "not found.") test.fail_test() if sys.platform == 'darwin' and TestMac.Xcode.Version()>="0600": diff --git a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-per-config-settings.py b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-per-config-settings.py index 7313e56343..6371509ac4 100644 --- a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-per-config-settings.py +++ b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-per-config-settings.py @@ -22,7 +22,7 @@ def CheckFileType(file, expected): o = proc.communicate()[0].strip() assert not proc.returncode if not expected in o: - print 'File: Expected %s, got %s' % (expected, o) + print('File: Expected {}, got {}'.format(expected, o)) test.fail_test() def HasCerts(): @@ -37,7 +37,7 @@ def CheckSignature(file): o = proc.communicate()[0].strip() assert not proc.returncode if "code object is not signed at all" in o: - print 'File %s not properly signed.' % (file) + print('File %s not properly signed.' % (file)) test.fail_test() def CheckEntitlements(file, expected_entitlements): @@ -49,10 +49,10 @@ def CheckEntitlements(file, expected_entitlements): data = temp.read() entitlements = ParseEntitlements(data) if not entitlements: - print 'No valid entitlements found in %s.' % (file) + print('No valid entitlements found in %s.' % (file)) test.fail_test() if entitlements != expected_entitlements: - print 'Unexpected entitlements found in %s.' % (file) + print('Unexpected entitlements found in %s.' % (file)) test.fail_test() def ParseEntitlements(data): @@ -75,17 +75,17 @@ def GetMachineBuild(): def CheckPlistvalue(plist, key, expected): if key not in plist: - print '%s not set in plist' % key + print('%s not set in plist' % key) test.fail_test() return actual = plist[key] if actual != expected: - print 'File: Expected %s, got %s for %s' % (expected, actual, key) + print('File: Expected {}, got {} for {}'.format(expected, actual, key)) test.fail_test() def CheckPlistNotSet(plist, key): if key in plist: - print '%s should not be set in plist' % key + print('%s should not be set in plist' % key) test.fail_test() return @@ -111,7 +111,7 @@ if sys.platform == 'darwin': xcode_version = TestMac.Xcode.Version() if xcode_version >= '0720': if len(plist) != 23: - print 'plist should have 23 entries, but it has %s' % len(plist) + print('plist should have 23 entries, but it has %s' % len(plist)) test.fail_test() # Values that will hopefully never change. diff --git a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-watch.py b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-watch.py index f5c4601d81..885637421a 100755 --- a/media/webrtc/trunk/tools/gyp/test/ios/gyptest-watch.py +++ b/media/webrtc/trunk/tools/gyp/test/ios/gyptest-watch.py @@ -14,7 +14,7 @@ import TestMac import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py b/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py index da27cc8288..850d933dbc 100644 --- a/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py +++ b/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py @@ -226,6 +226,7 @@ import shutil import stat import string import sys +import atexit import tempfile import time import traceback @@ -250,7 +251,7 @@ except ImportError: __all__.append('simple_diff') def is_List(e): - return type(e) is types.ListType \ + return type(e) is list \ or isinstance(e, UserList.UserList) try: @@ -261,12 +262,12 @@ except ImportError: if hasattr(types, 'UnicodeType'): def is_String(e): - return type(e) is types.StringType \ - or type(e) is types.UnicodeType \ + return type(e) is bytes \ + or type(e) is str \ or isinstance(e, UserString) else: def is_String(e): - return type(e) is types.StringType or isinstance(e, UserString) + return type(e) is bytes or isinstance(e, UserString) tempfile.template = 'testcmd.' if os.name in ('posix', 'nt'): @@ -274,7 +275,7 @@ if os.name in ('posix', 'nt'): else: tempfile.template = 'testcmd.' -re_space = re.compile('\s') +re_space = re.compile(r'\s') _Cleanup = [] @@ -282,7 +283,7 @@ _chain_to_exitfunc = None def _clean(): global _Cleanup - cleanlist = filter(None, _Cleanup) + cleanlist = [_f for _f in _Cleanup if _f] del _Cleanup[:] cleanlist.reverse() for test in cleanlist: @@ -298,7 +299,7 @@ except ImportError: _chain_to_exitfunc = sys.exitfunc except AttributeError: pass - sys.exitfunc = _clean + atexit.register(_clean) else: atexit.register(_clean) @@ -307,7 +308,7 @@ try: except NameError: def zip(*lists): result = [] - for i in xrange(min(map(len, lists))): + for i in range(min(list(map(len, lists)))): result.append(tuple(map(lambda l, i=i: l[i], lists))) return result @@ -316,7 +317,7 @@ class Collector: self.entries = [top] def __call__(self, arg, dirname, names): pathjoin = lambda n, d=dirname: os.path.join(d, n) - self.entries.extend(map(pathjoin, names)) + self.entries.extend(list(map(pathjoin, names))) def _caller(tblist, skip): string = "" @@ -433,9 +434,9 @@ def match_re(lines = None, res = None): s = "^" + res[i] + "$" try: expr = re.compile(s) - except re.error, e: + except re.error as e: msg = "Regular expression error in %s: %s" - raise re.error, msg % (repr(s), e[0]) + raise re.error(msg % (repr(s), e[0])) if not expr.search(lines[i]): return return 1 @@ -443,16 +444,16 @@ def match_re(lines = None, res = None): def match_re_dotall(lines = None, res = None): """ """ - if not type(lines) is type(""): + if not type(lines) is str: lines = string.join(lines, "\n") - if not type(res) is type(""): + if not type(res) is str: res = string.join(res, "\n") s = "^" + res + "$" try: expr = re.compile(s, re.DOTALL) - except re.error, e: + except re.error as e: msg = "Regular expression error in %s: %s" - raise re.error, msg % (repr(s), e[0]) + raise re.error(msg % (repr(s), e[0])) if expr.match(lines): return 1 @@ -470,20 +471,20 @@ else: """ sm = difflib.SequenceMatcher(None, a, b) def comma(x1, x2): - return x1+1 == x2 and str(x2) or '%s,%s' % (x1+1, x2) + return x1+1 == x2 and str(x2) or '{},{}'.format(x1+1, x2) result = [] for op, a1, a2, b1, b2 in sm.get_opcodes(): if op == 'delete': result.append("%sd%d" % (comma(a1, a2), b1)) - result.extend(map(lambda l: '< ' + l, a[a1:a2])) + result.extend(['< ' + l for l in a[a1:a2]]) elif op == 'insert': result.append("%da%s" % (a1, comma(b1, b2))) - result.extend(map(lambda l: '> ' + l, b[b1:b2])) + result.extend(['> ' + l for l in b[b1:b2]]) elif op == 'replace': - result.append("%sc%s" % (comma(a1, a2), comma(b1, b2))) - result.extend(map(lambda l: '< ' + l, a[a1:a2])) + result.append("{}c{}".format(comma(a1, a2), comma(b1, b2))) + result.extend(['< ' + l for l in a[a1:a2]]) result.append('---') - result.extend(map(lambda l: '> ' + l, b[b1:b2])) + result.extend(['> ' + l for l in b[b1:b2]]) return result def diff_re(a, b, fromfile='', tofile='', @@ -506,11 +507,11 @@ def diff_re(a, b, fromfile='', tofile='', s = "^" + aline + "$" try: expr = re.compile(s) - except re.error, e: + except re.error as e: msg = "Regular expression error in %s: %s" - raise re.error, msg % (repr(s), e[0]) + raise re.error(msg % (repr(s), e[0])) if not expr.search(bline): - result.append("%sc%s" % (i+1, i+1)) + result.append("{}c{}".format(i+1, i+1)) result.append('< ' + repr(a[i])) result.append('---') result.append('> ' + repr(b[i])) @@ -564,7 +565,7 @@ else: st = os.stat(f) except OSError: continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0111: + if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: return f return None @@ -652,14 +653,14 @@ except ImportError: universal_newlines = 1 def __init__(self, command, **kw): if kw.get('stderr') == 'STDOUT': - apply(popen2.Popen4.__init__, (self, command, 1)) + popen2.Popen4.__init__(*(self, command, 1)) else: - apply(popen2.Popen3.__init__, (self, command, 1)) + popen2.Popen3.__init__(*(self, command, 1)) self.stdin = self.tochild self.stdout = self.fromchild self.stderr = self.childerr def wait(self, *args, **kw): - resultcode = apply(popen2.Popen3.wait, (self,)+args, kw) + resultcode = popen2.Popen3.wait(*(self,)+args, **kw) if os.WIFEXITED(resultcode): return os.WEXITSTATUS(resultcode) elif os.WIFSIGNALED(resultcode): @@ -722,7 +723,7 @@ class Popen(subprocess.Popen): (errCode, written) = WriteFile(x, input) except ValueError: return self._close('stdin') - except (subprocess.pywintypes.error, Exception), why: + except (subprocess.pywintypes.error, Exception) as why: if why[0] in (109, errno.ESHUTDOWN): return self._close('stdin') raise @@ -743,7 +744,7 @@ class Popen(subprocess.Popen): (errCode, read) = ReadFile(x, nAvail, None) except ValueError: return self._close(which) - except (subprocess.pywintypes.error, Exception), why: + except (subprocess.pywintypes.error, Exception) as why: if why[0] in (109, errno.ESHUTDOWN): return self._close(which) raise @@ -762,7 +763,7 @@ class Popen(subprocess.Popen): try: written = os.write(self.stdin.fileno(), input) - except OSError, why: + except OSError as why: if why[0] == errno.EPIPE: #broken pipe return self._close('stdin') raise @@ -839,7 +840,7 @@ except NameError: -class TestCmd(object): +class TestCmd: """Class TestCmd """ @@ -882,7 +883,7 @@ class TestCmd(object): #self.diff_function = difflib.unified_diff self._dirlist = [] self._preserve = {'pass_test': 0, 'fail_test': 0, 'no_result': 0} - if os.environ.has_key('PRESERVE') and not os.environ['PRESERVE'] is '': + if 'PRESERVE' in os.environ and not os.environ['PRESERVE'] == '': self._preserve['pass_test'] = os.environ['PRESERVE'] self._preserve['fail_test'] = os.environ['PRESERVE'] self._preserve['no_result'] = os.environ['PRESERVE'] @@ -947,7 +948,7 @@ class TestCmd(object): def canonicalize(self, path): if is_List(path): - path = apply(os.path.join, tuple(path)) + path = os.path.join(*tuple(path)) if not os.path.isabs(path): path = os.path.join(self.workdir, path) return path @@ -981,7 +982,7 @@ class TestCmd(object): condition = self.condition if self._preserve[condition]: for dir in self._dirlist: - print "Preserved directory", dir + print("Preserved directory", dir) else: list = self._dirlist[:] list.reverse() @@ -1000,7 +1001,7 @@ class TestCmd(object): interpreter = None, arguments = None): if program: - if type(program) == type('') and not os.path.isabs(program): + if type(program) == str and not os.path.isabs(program): program = os.path.join(self._cwd, program) else: program = self.program @@ -1014,7 +1015,7 @@ class TestCmd(object): interpreter = [interpreter] cmd = list(interpreter) + cmd if arguments: - if type(arguments) == type(''): + if type(arguments) == str: arguments = string.split(arguments) cmd.extend(arguments) return cmd @@ -1028,17 +1029,17 @@ class TestCmd(object): difflib except NameError: def diff(self, a, b, name, *args, **kw): - print self.banner('Expected %s' % name) - print a - print self.banner('Actual %s' % name) - print b + print(self.banner('Expected %s' % name)) + print(a) + print(self.banner('Actual %s' % name)) + print(b) else: def diff(self, a, b, name, *args, **kw): - print self.banner(name) + print(self.banner(name)) args = (a.splitlines(), b.splitlines()) + args - lines = apply(self.diff_function, args, kw) + lines = self.diff_function(*args, **kw) for l in lines: - print l + print(l) def fail_test(self, condition = 1, function = None, skip = 0): """Cause the test to fail. @@ -1126,7 +1127,7 @@ class TestCmd(object): """ file = self.canonicalize(file) if mode[0] != 'r': - raise ValueError, "mode must begin with 'r'" + raise ValueError("mode must begin with 'r'") with open(file, mode) as f: result = f.read() return result @@ -1154,7 +1155,7 @@ class TestCmd(object): prepended unless it is enclosed in a [list]. """ cmd = self.command_args(program, interpreter, arguments) - cmd_string = string.join(map(self.escape, cmd), ' ') + cmd_string = string.join(list(map(self.escape, cmd)), ' ') if self.verbose: sys.stderr.write(cmd_string + "\n") if universal_newlines is None: @@ -1319,7 +1320,7 @@ class TestCmd(object): if sub is None: continue if is_List(sub): - sub = apply(os.path.join, tuple(sub)) + sub = os.path.join(*tuple(sub)) new = os.path.join(self.workdir, sub) try: os.mkdir(new) @@ -1409,7 +1410,7 @@ class TestCmd(object): """Find an executable file. """ if is_List(file): - file = apply(os.path.join, tuple(file)) + file = os.path.join(*tuple(file)) if not os.path.isabs(file): file = where_is(file, path, pathext) return file @@ -1431,7 +1432,7 @@ class TestCmd(object): the temporary working directory name with the specified arguments using the os.path.join() method. """ - return apply(os.path.join, (self.workdir,) + tuple(args)) + return os.path.join(*(self.workdir,) + tuple(args)) def readable(self, top, read=1): """Make the specified directory tree readable (read == 1) @@ -1508,12 +1509,12 @@ class TestCmd(object): def do_chmod(fname): try: st = os.stat(fname) except OSError: pass - else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0200)) + else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0o200)) else: def do_chmod(fname): try: st = os.stat(fname) except OSError: pass - else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0200)) + else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0o200)) if os.path.isfile(top): do_chmod(top) @@ -1586,7 +1587,7 @@ class TestCmd(object): """ file = self.canonicalize(file) if mode[0] != 'w': - raise ValueError, "mode must begin with 'w'" + raise ValueError("mode must begin with 'w'") with open(file, mode) as f: f.write(content) diff --git a/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py b/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py index a6e89ac32b..3e881168d8 100644 --- a/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py +++ b/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py @@ -184,7 +184,7 @@ else: module_suffix = '.so' def is_List(e): - return type(e) is types.ListType \ + return type(e) is list \ or isinstance(e, UserList.UserList) def is_writable(f): @@ -227,7 +227,7 @@ class TestCommon(TestCmd): calling the base class initialization, and then changing directory to the workdir. """ - apply(TestCmd.__init__, [self], kw) + TestCmd.__init__(*[self], **kw) os.chdir(self.workdir) def must_be_writable(self, *files): @@ -237,13 +237,13 @@ class TestCommon(TestCmd): them. Exits FAILED if any of the files does not exist or is not writable. """ - files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files) + files = [is_List(x) and os.path.join(*x) or x for x in files] existing, missing = separate_files(files) - unwritable = filter(lambda x, iw=is_writable: not iw(x), existing) + unwritable = list(filter(lambda x, iw=is_writable: not iw(x), existing)) if missing: - print "Missing files: `%s'" % string.join(missing, "', `") + print("Missing files: `%s'" % string.join(missing, "', `")) if unwritable: - print "Unwritable files: `%s'" % string.join(unwritable, "', `") + print("Unwritable files: `%s'" % string.join(unwritable, "', `")) self.fail_test(missing + unwritable) def must_contain(self, file, required, mode = 'rb'): @@ -252,11 +252,11 @@ class TestCommon(TestCmd): file_contents = self.read(file, mode) contains = (string.find(file_contents, required) != -1) if not contains: - print "File `%s' does not contain required string." % file - print self.banner('Required string ') - print required - print self.banner('%s contents ' % file) - print file_contents + print("File `%s' does not contain required string." % file) + print(self.banner('Required string ')) + print(required) + print(self.banner('%s contents ' % file)) + print(file_contents) self.fail_test(not contains) def must_contain_all_lines(self, output, lines, title=None, find=None): @@ -323,10 +323,10 @@ class TestCommon(TestCmd): pathname will be constructed by concatenating them. Exits FAILED if any of the files does not exist. """ - files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files) - missing = filter(lambda x: not os.path.exists(x), files) + files = [is_List(x) and os.path.join(*x) or x for x in files] + missing = [x for x in files if not os.path.exists(x)] if missing: - print "Missing files: `%s'" % string.join(missing, "', `") + print("Missing files: `%s'" % string.join(missing, "', `")) self.fail_test(missing) def must_match(self, file, expect, mode = 'rb'): @@ -341,7 +341,7 @@ class TestCommon(TestCmd): except KeyboardInterrupt: raise except: - print "Unexpected contents of `%s'" % file + print("Unexpected contents of `%s'" % file) self.diff(expect, file_contents, 'contents ') raise @@ -351,11 +351,11 @@ class TestCommon(TestCmd): file_contents = self.read(file, mode) contains = (string.find(file_contents, banned) != -1) if contains: - print "File `%s' contains banned string." % file - print self.banner('Banned string ') - print banned - print self.banner('%s contents ' % file) - print file_contents + print("File `%s' contains banned string." % file) + print(self.banner('Banned string ')) + print(banned) + print(self.banner('%s contents ' % file)) + print(file_contents) self.fail_test(contains) def must_not_contain_any_line(self, output, lines, title=None, find=None): @@ -395,10 +395,10 @@ class TestCommon(TestCmd): which case the pathname will be constructed by concatenating them. Exits FAILED if any of the files exists. """ - files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files) - existing = filter(os.path.exists, files) + files = [is_List(x) and os.path.join(*x) or x for x in files] + existing = list(filter(os.path.exists, files)) if existing: - print "Unexpected files exist: `%s'" % string.join(existing, "', `") + print("Unexpected files exist: `%s'" % string.join(existing, "', `")) self.fail_test(existing) def must_not_be_writable(self, *files): @@ -408,13 +408,13 @@ class TestCommon(TestCmd): them. Exits FAILED if any of the files does not exist or is writable. """ - files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files) + files = [is_List(x) and os.path.join(*x) or x for x in files] existing, missing = separate_files(files) - writable = filter(is_writable, existing) + writable = list(filter(is_writable, existing)) if missing: - print "Missing files: `%s'" % string.join(missing, "', `") + print("Missing files: `%s'" % string.join(missing, "', `")) if writable: - print "Writable files: `%s'" % string.join(writable, "', `") + print("Writable files: `%s'" % string.join(writable, "', `")) self.fail_test(missing + writable) def _complete(self, actual_stdout, expected_stdout, @@ -427,21 +427,21 @@ class TestCommon(TestCmd): expect = '' if status != 0: expect = " (expected %s)" % str(status) - print "%s returned %s%s" % (self.program, str(_status(self)), expect) - print self.banner('STDOUT ') - print actual_stdout - print self.banner('STDERR ') - print actual_stderr + print("{} returned {}{}".format(self.program, str(_status(self)), expect)) + print(self.banner('STDOUT ')) + print(actual_stdout) + print(self.banner('STDERR ')) + print(actual_stderr) self.fail_test() if not expected_stdout is None and not match(actual_stdout, expected_stdout): self.diff(expected_stdout, actual_stdout, 'STDOUT ') if actual_stderr: - print self.banner('STDERR ') - print actual_stderr + print(self.banner('STDERR ')) + print(actual_stderr) self.fail_test() if not expected_stderr is None and not match(actual_stderr, expected_stderr): - print self.banner('STDOUT ') - print actual_stdout + print(self.banner('STDOUT ')) + print(actual_stdout) self.diff(expected_stderr, actual_stderr, 'STDERR ') self.fail_test() @@ -463,20 +463,18 @@ class TestCommon(TestCmd): arguments = options + " " + arguments try: - return apply(TestCmd.start, - (self, program, interpreter, arguments, universal_newlines), - kw) + return TestCmd.start(*(self, program, interpreter, arguments, universal_newlines), **kw) except KeyboardInterrupt: raise - except Exception, e: - print self.banner('STDOUT ') + except Exception as e: + print(self.banner('STDOUT ')) try: - print self.stdout() + print(self.stdout()) except IndexError: pass - print self.banner('STDERR ') + print(self.banner('STDERR ')) try: - print self.stderr() + print(self.stderr()) except IndexError: pass cmd_args = self.command_args(program, interpreter, arguments) @@ -501,7 +499,7 @@ class TestCommon(TestCmd): command. A value of None means don't test exit status. """ - apply(TestCmd.finish, (self, popen,), kw) + TestCmd.finish(*(self, popen,), **kw) match = kw.get('match', self.match) self._complete(self.stdout(), stdout, self.stderr(), stderr, status, match) @@ -539,7 +537,7 @@ class TestCommon(TestCmd): arguments = options + " " + arguments kw['arguments'] = arguments match = kw.pop('match', self.match) - apply(TestCmd.run, [self], kw) + TestCmd.run(*[self], **kw) self._complete(self.stdout(), stdout, self.stderr(), stderr, status, match) diff --git a/media/webrtc/trunk/tools/gyp/test/lib/TestGyp.py b/media/webrtc/trunk/tools/gyp/test/lib/TestGyp.py index fc7b135817..01084d4fb4 100644 --- a/media/webrtc/trunk/tools/gyp/test/lib/TestGyp.py +++ b/media/webrtc/trunk/tools/gyp/test/lib/TestGyp.py @@ -6,7 +6,9 @@ TestGyp.py: a testing framework for GYP integration tests. """ +from __future__ import print_function import collections +import collections.abc from contextlib import contextmanager import itertools import os @@ -282,13 +284,13 @@ class TestGypBase(TestCommon.TestCommon): that expect exact output from the command (make) can just set stdout= when they call the run_build() method. """ - print "Build is not up-to-date:" - print self.banner('STDOUT ') - print self.stdout() + print("Build is not up-to-date:") + print(self.banner('STDOUT ')) + print(self.stdout()) stderr = self.stderr() if stderr: - print self.banner('STDERR ') - print stderr + print(self.banner('STDERR ')) + print(stderr) def run_gyp(self, gyp_file, *args, **kw): """ @@ -326,7 +328,7 @@ class TestGypBase(TestCommon.TestCommon): the tool-specific subclasses or clutter the tests themselves with platform-specific code. """ - if kw.has_key('SYMROOT'): + if 'SYMROOT' in kw: del kw['SYMROOT'] super(TestGypBase, self).run(*args, **kw) @@ -492,7 +494,7 @@ class TestGypCMake(TestGypBase): if status is None: kw['status'] = None else: - if not isinstance(status, collections.Iterable): status = (status,) + if not isinstance(status, collections.abc.Iterable): status = (status,) kw['status'] = list(itertools.chain((0,), status)) self.cmake_build(gyp_file, target, **kw) kw['status'] = status @@ -556,7 +558,7 @@ class TestGypMake(TestGypBase): # Makefile.gyp_filename), so use that if there is no Makefile. chdir = kw.get('chdir', '') if not os.path.exists(os.path.join(chdir, 'Makefile')): - print "NO Makefile in " + os.path.join(chdir, 'Makefile') + print("NO Makefile in " + os.path.join(chdir, 'Makefile')) arguments.insert(0, '-f') arguments.insert(1, os.path.splitext(gyp_file)[0] + '.Makefile') kw['arguments'] = arguments @@ -663,7 +665,7 @@ def FindMSBuildInstallation(msvs_version = 'auto'): msbuild_basekey = r'HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions' if not registry.KeyExists(msbuild_basekey): - print 'Error: could not find MSBuild base registry entry' + print('Error: could not find MSBuild base registry entry') return None msbuild_version = None @@ -672,7 +674,7 @@ def FindMSBuildInstallation(msvs_version = 'auto'): if registry.KeyExists(msbuild_basekey + '\\' + msbuild_test_version): msbuild_version = msbuild_test_version else: - print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' + print('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' 'but corresponding MSBuild "%s" was not found.' % (msvs_version, msbuild_version)) if not msbuild_version: @@ -682,13 +684,13 @@ def FindMSBuildInstallation(msvs_version = 'auto'): msbuild_version = msbuild_test_version break if not msbuild_version: - print 'Error: could not find MSBuild registry entry' + print('Error: could not find MSBuild registry entry') return None msbuild_path = registry.GetValue(msbuild_basekey + '\\' + msbuild_version, 'MSBuildToolsPath') if not msbuild_path: - print 'Error: could not get MSBuild registry entry value' + print('Error: could not get MSBuild registry entry value') return None return os.path.join(msbuild_path, 'MSBuild.exe') @@ -730,7 +732,7 @@ def FindVisualStudioInstallation(): msbuild_path = FindMSBuildInstallation(msvs_version) return build_tool, uses_msbuild, msbuild_path else: - print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' + print('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' 'but corresponding "%s" was not found.' % (msvs_version, path)) # Neither GYP_MSVS_VERSION nor the path help us out. Iterate through # the choices looking for a match. @@ -742,7 +744,7 @@ def FindVisualStudioInstallation(): uses_msbuild = msvs_version >= '2010' msbuild_path = FindMSBuildInstallation(msvs_version) return build_tool, uses_msbuild, msbuild_path - print 'Error: could not find devenv' + print('Error: could not find devenv') sys.exit(1) class TestGypOnMSToolchain(TestGypBase): @@ -887,10 +889,10 @@ class TestGypMSVS(TestGypOnMSToolchain): Verifies that a build of the specified Visual Studio target is up to date. Beware that VS2010 will behave strangely if you build under - C:\USERS\yourname\AppData\Local. It will cause needless work. The ouptut + C:\USERS\\yourname\\AppData\\Local. It will cause needless work. The ouptut will be "1 succeeded and 0 up to date". MSBuild tracing reveals that: - "Project 'C:\Users\...\AppData\Local\...vcxproj' not up to date because - 'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 10.0\VC\BIN\1033\CLUI.DLL' + "Project 'C:\Users\\...\\AppData\\Local\\...vcxproj' not up to date because + 'C:\\PROGRAM FILES (X86)\\MICROSOFT VISUAL STUDIO 10.0\\VC\\BIN\1033\\CLUI.DLL' was modified at 02/21/2011 17:03:30, which is newer than '' which was modified at 01/01/0001 00:00:00. @@ -1190,4 +1192,4 @@ def TestGyp(*args, **kw): for format_class in format_class_list: if format == format_class.format: return format_class(*args, **kw) - raise Exception, "unknown format %r" % format + raise Exception("unknown format %r" % format) diff --git a/media/webrtc/trunk/tools/gyp/test/lib/TestMac.py b/media/webrtc/trunk/tools/gyp/test/lib/TestMac.py index 68605d77b1..4db31f0cff 100644 --- a/media/webrtc/trunk/tools/gyp/test/lib/TestMac.py +++ b/media/webrtc/trunk/tools/gyp/test/lib/TestMac.py @@ -23,17 +23,17 @@ def CheckFileType(test, file, archs): pattern = re.compile('^Architectures in the fat file: (.*) are: (.*)$') match = pattern.match(o) if match is None: - print 'Ouput does not match expected pattern: %s' % (pattern.pattern) + print('Ouput does not match expected pattern: %s' % (pattern.pattern)) test.fail_test() else: found_file, found_archs = match.groups() if found_file != file or set(found_archs.split()) != set(archs): - print 'Expected file %s with arch %s, got %s with arch %s' % ( - file, ' '.join(archs), found_file, found_archs) + print('Expected file {} with arch {}, got {} with arch {}'.format( + file, ' '.join(archs), found_file, found_archs)) test.fail_test() -class XcodeInfo(object): +class XcodeInfo: """Simplify access to Xcode informations.""" def __init__(self): diff --git a/media/webrtc/trunk/tools/gyp/test/lib/TestWin.py b/media/webrtc/trunk/tools/gyp/test/lib/TestWin.py index 7627197b1f..62b5f5e30a 100644 --- a/media/webrtc/trunk/tools/gyp/test/lib/TestWin.py +++ b/media/webrtc/trunk/tools/gyp/test/lib/TestWin.py @@ -12,7 +12,7 @@ import re import sys import subprocess -class Registry(object): +class Registry: def _QueryBase(self, sysdir, key, value): """Use reg.exe to read a particular key. @@ -63,7 +63,7 @@ class Registry(object): text = None try: text = self._QueryBase('Sysnative', key, value) - except OSError, e: + except OSError as e: if e.errno == errno.ENOENT: text = self._QueryBase('System32', key, value) else: diff --git a/media/webrtc/trunk/tools/gyp/test/linux/ldflags-duplicates/check-ldflags.py b/media/webrtc/trunk/tools/gyp/test/linux/ldflags-duplicates/check-ldflags.py index 0515da95e4..0a7d25efc3 100755 --- a/media/webrtc/trunk/tools/gyp/test/linux/ldflags-duplicates/check-ldflags.py +++ b/media/webrtc/trunk/tools/gyp/test/linux/ldflags-duplicates/check-ldflags.py @@ -12,13 +12,13 @@ import sys def CheckContainsFlags(args, substring): if args.find(substring) is -1: - print 'ERROR: Linker arguments "%s" are missing in "%s"' % (substring, args) + print('ERROR: Linker arguments "{}" are missing in "{}"'.format(substring, args)) return False; return True; if __name__ == '__main__': args = " ".join(sys.argv) - print "args = " +args + print("args = " +args) if not CheckContainsFlags(args, 'lib1.a -Wl,--no-whole-archive') \ or not CheckContainsFlags(args, 'lib2.a -Wl,--no-whole-archive'): sys.exit(1); diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-assets-catalog.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-assets-catalog.py index ca76b513aa..1a352c8874 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-assets-catalog.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-assets-catalog.py @@ -17,12 +17,12 @@ import subprocess import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) def ExpectEq(expected, actual): if expected != actual: - print >>sys.stderr, 'Expected "%s", got "%s"' % (expected, actual) + print('Expected "{}", got "{}"'.format(expected, actual), file=sys.stderr) test.fail_test() def ls(path): diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-error.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-error.py index c6fe33f128..f70488c387 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-error.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app-error.py @@ -14,7 +14,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) expected_error = 'Old-style plist parser: missing semicolon in dictionary' diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app.py index be92d01aed..9cea21a997 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-app.py @@ -18,7 +18,7 @@ import sys if sys.platform in ('darwin', 'win32'): - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) @@ -26,12 +26,12 @@ def CheckFileXMLPropertyList(file): output = subprocess.check_output(['file', file]) # The double space after XML is intentional. if not 'XML document text' in output: - print 'File: Expected XML document text, got %s' % output + print('File: Expected XML document text, got %s' % output) test.fail_test() def ExpectEq(expected, actual): if expected != actual: - print >>sys.stderr, 'Expected "%s", got "%s"' % (expected, actual) + print('Expected "{}", got "{}"'.format(expected, actual), file=sys.stderr) test.fail_test() def ls(path): diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-bundle-resources.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-bundle-resources.py index e9eddb70fa..45b28f438d 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-bundle-resources.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-bundle-resources.py @@ -15,7 +15,7 @@ import stat import sys if sys.platform in ('darwin'): - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-copies.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-copies.py index 4146441862..59156e5054 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-copies.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-copies.py @@ -15,7 +15,7 @@ import sys import time if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-depend-on-bundle.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-depend-on-bundle.py index 486fbfe2da..568f741034 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-depend-on-bundle.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-depend-on-bundle.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-framework.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-framework.py index 553cc9f648..efbfaf0343 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-framework.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-framework.py @@ -14,7 +14,7 @@ import os import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) @@ -67,12 +67,12 @@ if sys.platform == 'darwin': # Check that no other files get added to the bundle. if set(ls(test.built_file_path('Test Framework.framework', chdir='framework'))) != \ - set(['Versions/A/Test Framework', + {'Versions/A/Test Framework', 'Versions/A/Resources/Info.plist', 'Versions/A/Resources/English.lproj/InfoPlist.strings', 'Test Framework', 'Versions/A/Libraries/empty.c', # Written by a gyp action. - ]): + }: test.fail_test() test.pass_test() diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-infoplist-process.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-infoplist-process.py index 2e5168477e..dff0991356 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-infoplist-process.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-infoplist-process.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-installname.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-installname.py index 3fc7152242..0cc80d9200 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-installname.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-installname.py @@ -16,7 +16,7 @@ import subprocess import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-ldflags-passed-to-libtool.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-ldflags-passed-to-libtool.py index 48afcd46bc..5c9c17b3f4 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-ldflags-passed-to-libtool.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-ldflags-passed-to-libtool.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode'], diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-loadable-module.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-loadable-module.py index 158a930552..19242b040b 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-loadable-module.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-loadable-module.py @@ -15,7 +15,7 @@ import struct import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-lto.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-lto.py index 5171544750..d417135d3f 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-lto.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-lto.py @@ -44,7 +44,7 @@ if sys.platform == 'darwin': elif ': LLVM bit-code ' in o: objtype = 'llvm' if objtype != t_expected: - print 'Expected %s, got %s' % (t_expected, objtype) + print('Expected {}, got {}'.format(t_expected, objtype)) test.fail_test() ObjType(ObjPath('cfile', 'lto'), 'llvm') diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-missing-cfbundlesignature.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-missing-cfbundlesignature.py index 43cab77bdf..0289c92e31 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-missing-cfbundlesignature.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-missing-cfbundlesignature.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-non-strs-flattened-to-env.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-non-strs-flattened-to-env.py index b802619ba2..571c12523b 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-non-strs-flattened-to-env.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-non-strs-flattened-to-env.py @@ -14,7 +14,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-defaults.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-defaults.py index 892a0c4b06..f223e354a5 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-defaults.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-defaults.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-fail.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-fail.py index 9cd5d47d28..319338fe8a 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-fail.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-fail.py @@ -39,7 +39,7 @@ if sys.platform == 'darwin': stderr=subprocess.STDOUT) out, err = job.communicate() if job.returncode != 0: - print out + print(out) raise Exception('Error %d running xcodebuild' % job.returncode) if out.startswith('Xcode 3.'): test.pass_test() diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-rebuild.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-rebuild.py index e615d06786..4473ce7351 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-rebuild.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-rebuild.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sdkroot.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sdkroot.py index f7d41cd25a..38733d3f77 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sdkroot.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sdkroot.py @@ -16,7 +16,7 @@ import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sourceless-module.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sourceless-module.py index c34bc546bd..a1280c97fe 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sourceless-module.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-sourceless-module.py @@ -13,7 +13,7 @@ import TestGyp import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip-default.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip-default.py index f73fa1124c..6c4d65bdd8 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip-default.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip-default.py @@ -34,14 +34,14 @@ if sys.platform == 'darwin': # Filter out mysterious "00 0000 OPT radr://5614542" symbol which # is apparently only printed on the bots (older toolchain?). # Yes, "radr", not "rdar". - o = ''.join(filter(lambda s: 'radr://5614542' not in s, o.splitlines(True))) + o = ''.join([s for s in o.splitlines(True) if 'radr://5614542' not in s]) o = o.replace('A', 'T') o = re.sub(r'^[a-fA-F0-9]+', 'XXXXXXXX', o, flags=re.MULTILINE) assert not proc.returncode if o != o_expected: - print 'Stripping: Expected symbols """\n%s""", got """\n%s"""' % ( - o_expected, o) + print('Stripping: Expected symbols """\n{}""", got """\n{}"""'.format( + o_expected, o)) test.fail_test() CheckNsyms(OutPath('libsingle_dylib.dylib'), diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip.py index a729521e18..357f48f59a 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-strip.py @@ -33,7 +33,7 @@ if sys.platform == 'darwin': m = r.search(o) n = int(m.group(1)) if n != n_expected: - print 'Stripping: Expected %d symbols, got %d' % (n_expected, n) + print('Stripping: Expected %d symbols, got %d' % (n_expected, n)) test.fail_test() # Starting with Xcode 5.0, clang adds an additional symbols to the compiled diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-swift-library.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-swift-library.py index dde7a62351..961128a375 100644 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-swift-library.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-swift-library.py @@ -16,7 +16,7 @@ import sys import subprocess if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['xcode']) @@ -26,7 +26,7 @@ if sys.platform == 'darwin': output = subprocess.check_output(['nm', '-j', path]) idx = output.find(symbol) if idx == -1: - print 'Swift: Could not find symobl: %s' % symbol + print('Swift: Could not find symobl: %s' % symbol) test.fail_test() test_cases = [] diff --git a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-xcode-env-order.py b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-xcode-env-order.py index 6e7ca2413f..9898c226ee 100755 --- a/media/webrtc/trunk/tools/gyp/test/mac/gyptest-xcode-env-order.py +++ b/media/webrtc/trunk/tools/gyp/test/mac/gyptest-xcode-env-order.py @@ -15,7 +15,7 @@ import subprocess import sys if sys.platform == 'darwin': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) diff --git a/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py b/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py index 1f5103315c..9542a5d895 100755 --- a/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py +++ b/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py @@ -10,7 +10,6 @@ optional. """ # Python 2.5 needs this for the with statement. -from __future__ import with_statement import os import TestGyp diff --git a/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_nm.py b/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_nm.py index f0f1efcf73..578d680bc5 100755 --- a/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_nm.py +++ b/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_nm.py @@ -3,6 +3,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) with open('RAN_MY_NM', 'w') as f: f.write('RAN_MY_NM') diff --git a/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_readelf.py b/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_readelf.py index 40e303cd76..6ec7c9ea22 100755 --- a/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_readelf.py +++ b/media/webrtc/trunk/tools/gyp/test/make_global_settings/full-toolchain/my_readelf.py @@ -3,6 +3,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys -print sys.argv +print(sys.argv) with open('RAN_MY_READELF', 'w') as f: f.write('RAN_MY_READELF') diff --git a/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions-unsorted.py b/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions-unsorted.py index 90d3c92e4c..1be553726a 100644 --- a/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions-unsorted.py +++ b/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions-unsorted.py @@ -9,10 +9,11 @@ Make sure lots of actions in the same target don't cause exceeding command line length. """ +from __future__ import print_function import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) import TestGyp diff --git a/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions.py b/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions.py index f2e719bb70..e0d75c983b 100644 --- a/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions.py +++ b/media/webrtc/trunk/tools/gyp/test/many-actions/gyptest-many-actions.py @@ -9,10 +9,11 @@ Make sure lots of actions in the same target don't cause exceeding command line length. """ +from __future__ import print_function import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/msvs/config_attrs/gyptest-config_attrs.py b/media/webrtc/trunk/tools/gyp/test/msvs/config_attrs/gyptest-config_attrs.py index d5603744db..b01f3c9311 100644 --- a/media/webrtc/trunk/tools/gyp/test/msvs/config_attrs/gyptest-config_attrs.py +++ b/media/webrtc/trunk/tools/gyp/test/msvs/config_attrs/gyptest-config_attrs.py @@ -16,7 +16,7 @@ import os import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stderr.py b/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stderr.py index f4860624f3..fc1b04331c 100644 --- a/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stderr.py +++ b/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stderr.py @@ -4,4 +4,4 @@ # found in the LICENSE file. import sys -print >>sys.stderr, "This will go to stderr" +print("This will go to stderr", file=sys.stderr) diff --git a/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stdout.py b/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stdout.py index 2b58d2a374..8881d44d64 100644 --- a/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stdout.py +++ b/media/webrtc/trunk/tools/gyp/test/msvs/rules_stdout_stderr/rule_stdout.py @@ -3,4 +3,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -print "This will go to stdout" +#!/usr/bin/env python +# Copyright (c) 2015 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +print("This will go to stdout") diff --git a/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py b/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py index cb59d7e3c1..16556ef9a8 100755 --- a/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py +++ b/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py @@ -13,7 +13,7 @@ import os import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py b/media/webrtc/trunk/tools/gyp/test/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py index 1b8e812eb2..b8277509de 100755 --- a/media/webrtc/trunk/tools/gyp/test/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py +++ b/media/webrtc/trunk/tools/gyp/test/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py @@ -24,7 +24,7 @@ test = TestGyp.TestGyp(formats=['ninja']) if not os.environ.get('ProgramFiles(x86)'): # TODO(scottmg) - print 'Skipping test on x86, http://crbug.com/365833' + print('Skipping test on x86, http://crbug.com/365833') test.pass_test() test.run_gyp('solibs_avoid_relinking.gyp') diff --git a/media/webrtc/trunk/tools/gyp/test/rules-dirname/gyptest-dirname.py b/media/webrtc/trunk/tools/gyp/test/rules-dirname/gyptest-dirname.py index 9b8949b32c..bed1f823f1 100755 --- a/media/webrtc/trunk/tools/gyp/test/rules-dirname/gyptest-dirname.py +++ b/media/webrtc/trunk/tools/gyp/test/rules-dirname/gyptest-dirname.py @@ -8,12 +8,13 @@ Verifies simple rules when using an explicit build target of 'all'. """ +from __future__ import print_function import TestGyp import os import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/rules-variables/gyptest-rules-variables.py b/media/webrtc/trunk/tools/gyp/test/rules-variables/gyptest-rules-variables.py index c1825e0c13..b2e0826ef4 100755 --- a/media/webrtc/trunk/tools/gyp/test/rules-variables/gyptest-rules-variables.py +++ b/media/webrtc/trunk/tools/gyp/test/rules-variables/gyptest-rules-variables.py @@ -8,10 +8,11 @@ Verifies rules related variables are expanded. """ +from __future__ import print_function import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/rules/gyptest-all.py b/media/webrtc/trunk/tools/gyp/test/rules/gyptest-all.py index e6e637ebbf..4aa925d501 100755 --- a/media/webrtc/trunk/tools/gyp/test/rules/gyptest-all.py +++ b/media/webrtc/trunk/tools/gyp/test/rules/gyptest-all.py @@ -11,7 +11,7 @@ Verifies simple rules when using an explicit build target of 'all'. import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/rules/gyptest-default.py b/media/webrtc/trunk/tools/gyp/test/rules/gyptest-default.py index 65b79dacd6..29c9ea97e6 100755 --- a/media/webrtc/trunk/tools/gyp/test/rules/gyptest-default.py +++ b/media/webrtc/trunk/tools/gyp/test/rules/gyptest-default.py @@ -11,7 +11,7 @@ Verifies simple rules when using an explicit build target of 'all'. import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/rules/src/copy-file.py b/media/webrtc/trunk/tools/gyp/test/rules/src/copy-file.py index 5a5feae1f2..c95252b975 100755 --- a/media/webrtc/trunk/tools/gyp/test/rules/src/copy-file.py +++ b/media/webrtc/trunk/tools/gyp/test/rules/src/copy-file.py @@ -5,7 +5,7 @@ # found in the LICENSE file. import sys -contents = open(sys.argv[1], 'r').read() +contents = open(sys.argv[1]).read() open(sys.argv[2], 'wb').write(contents) sys.exit(0) diff --git a/media/webrtc/trunk/tools/gyp/test/standalone/gyptest-standalone.py b/media/webrtc/trunk/tools/gyp/test/standalone/gyptest-standalone.py index 87143706ab..a9faef1117 100644 --- a/media/webrtc/trunk/tools/gyp/test/standalone/gyptest-standalone.py +++ b/media/webrtc/trunk/tools/gyp/test/standalone/gyptest-standalone.py @@ -26,7 +26,7 @@ for root, dirs, files in os.walk("."): file = os.path.join(root, file) contents = open(file).read() if 'standalone.gyp' in contents: - print 'gyp file referenced in generated output: %s' % file + print('gyp file referenced in generated output: %s' % file) test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-ignore-env.py b/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-ignore-env.py index 1cf3308dc4..6d1cdbd0ce 100755 --- a/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-ignore-env.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-ignore-env.py @@ -39,7 +39,7 @@ test.run_gyp('commands.gyp', contents = test.read('commands.gypd').replace('\r', '') expect = test.read('commands.gypd.golden').replace('\r', '') if not test.match(contents, expect): - print "Unexpected contents of `commands.gypd'" + print("Unexpected contents of `commands.gypd'") test.diff(expect, contents, 'commands.gypd ') test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-repeated.py b/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-repeated.py index b95fe2d75e..eb76542250 100755 --- a/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-repeated.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands-repeated.py @@ -31,7 +31,7 @@ test.run_gyp('commands-repeated.gyp', contents = test.read('commands-repeated.gypd').replace('\r\n', '\n') expect = test.read('commands-repeated.gypd.golden').replace('\r\n', '\n') if not test.match(contents, expect): - print "Unexpected contents of `commands-repeated.gypd'" + print("Unexpected contents of `commands-repeated.gypd'") test.diff(expect, contents, 'commands-repeated.gypd ') test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands.py b/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands.py index ef1af8c525..1b0d256eb0 100755 --- a/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/commands/gyptest-commands.py @@ -32,7 +32,7 @@ test.run_gyp('commands.gyp', contents = test.read('commands.gypd').replace('\r', '') expect = test.read('commands.gypd.golden').replace('\r', '') if not test.match(contents, expect): - print "Unexpected contents of `commands.gypd'" + print("Unexpected contents of `commands.gypd'") test.diff(expect, contents, 'commands.gypd ') test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/variables/commands/repeated_multidir/print_cwd_basename.py b/media/webrtc/trunk/tools/gyp/test/variables/commands/repeated_multidir/print_cwd_basename.py index ace9ed6b80..52c99e0c8c 100755 --- a/media/webrtc/trunk/tools/gyp/test/variables/commands/repeated_multidir/print_cwd_basename.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/commands/repeated_multidir/print_cwd_basename.py @@ -7,4 +7,4 @@ import os import os.path -print os.path.basename(os.getcwd()) +print(os.path.basename(os.getcwd())) diff --git a/media/webrtc/trunk/tools/gyp/test/variables/commands/test.py b/media/webrtc/trunk/tools/gyp/test/variables/commands/test.py index 4d9ca6d1ab..a76c00572a 100644 --- a/media/webrtc/trunk/tools/gyp/test/variables/commands/test.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/commands/test.py @@ -1 +1 @@ -print "sample\\path\\foo.cpp" +print("sample\\path\\foo.cpp") diff --git a/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist-golden.py b/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist-golden.py index 55eaf9db46..7162043390 100644 --- a/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist-golden.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist-golden.py @@ -36,14 +36,14 @@ contents = test.read('src/filelist.gypd').replace( '\r', '').replace('\\\\', '/') expect = test.read('filelist.gypd.golden').replace('\r', '') if not test.match(contents, expect): - print "Unexpected contents of `src/filelist.gypd'" + print("Unexpected contents of `src/filelist.gypd'") test.diff(expect, contents, 'src/filelist.gypd ') test.fail_test() contents = test.read('src/names.txt') expect = 'John\nJacob\nJingleheimer\nSchmidt\n' if not test.match(contents, expect): - print "Unexpected contents of `src/names.txt'" + print("Unexpected contents of `src/names.txt'") test.diff(expect, contents, 'src/names.txt ') test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist.py b/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist.py index 84a6cba5f4..b12084c21c 100755 --- a/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist.py +++ b/media/webrtc/trunk/tools/gyp/test/variables/filelist/gyptest-filelist.py @@ -22,7 +22,7 @@ test.build('filelist2.gyp', 'foo', chdir=CHDIR) contents = test.read('src/dummy_foo').replace('\r', '') expect = 'John\nJacob\nJingleheimer\nSchmidt\n' if not test.match(contents, expect): - print "Unexpected contents of `src/dummy_foo'" + print("Unexpected contents of `src/dummy_foo'") test.diff(expect, contents, 'src/dummy_foo') test.fail_test() diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-enable-enhanced-instruction-set.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-enable-enhanced-instruction-set.py index 78a924aba3..ac6af8dafc 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-enable-enhanced-instruction-set.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-enable-enhanced-instruction-set.py @@ -8,13 +8,14 @@ Test VCCLCompilerTool EnableEnhancedInstructionSet setting. """ +from __future__ import print_function import TestGyp import os import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp() diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py index 17c29e235f..56e1027e49 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py @@ -8,6 +8,7 @@ Make sure function-level linking setting is extracted properly. """ +from __future__ import print_function import TestGyp import sys @@ -22,10 +23,10 @@ if sys.platform == 'win32': def CheckForSectionString(binary, search_for, should_exist): output = test.run_dumpbin('/headers', binary) if should_exist and search_for not in output: - print 'Did not find "%s" in %s' % (search_for, binary) + print('Did not find "%s" in %s' % (search_for, binary)) test.fail_test() elif not should_exist and search_for in output: - print 'Found "%s" in %s (and shouldn\'t have)' % (search_for, binary) + print('Found "%s" in %s (and shouldn\'t have)' % (search_for, binary)) test.fail_test() def Object(proj, obj): diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-command-quote.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-command-quote.py index bd93ac5e92..871f35b1a4 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-command-quote.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-command-quote.py @@ -12,12 +12,13 @@ application in the path. Specifically, this means not quoting something like than calling "x.bat". """ +from __future__ import print_function import TestGyp import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['msvs', 'ninja']) diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-defrelink.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-defrelink.py index cec0ea1870..733a5aa797 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-defrelink.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-defrelink.py @@ -8,12 +8,13 @@ Make sure a relink is performed when a .def file is touched. """ +from __future__ import print_function import TestGyp import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) test = TestGyp.TestGyp(formats=['msvs', 'ninja']) diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-uac.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-uac.py index 131e07ec1f..731e50a135 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-uac.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-uac.py @@ -68,8 +68,8 @@ if sys.platform == 'win32': test.fail_test(len(execution_level) != 1) execution_level = execution_level[0].attributes test.fail_test(not ( - execution_level.has_key('level') and - execution_level.has_key('uiAccess') and + 'level' in execution_level and + 'uiAccess' in execution_level and execution_level['level'].nodeValue == 'asInvoker' and execution_level['uiAccess'].nodeValue == 'false')) @@ -87,8 +87,8 @@ if sys.platform == 'win32': test.fail_test(len(execution_level) != 1) execution_level = execution_level[0].attributes test.fail_test(not ( - execution_level.has_key('level') and - execution_level.has_key('uiAccess') and + 'level' in execution_level and + 'uiAccess' in execution_level and execution_level['level'].nodeValue == 'requireAdministrator' and execution_level['uiAccess'].nodeValue == 'true')) diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-app-revision.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-app-revision.py index e5c5a71335..31195c2cf3 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-app-revision.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-app-revision.py @@ -8,6 +8,7 @@ Make sure msvs_application_type_revision works correctly. """ +from __future__ import print_function import TestGyp import os @@ -16,7 +17,7 @@ import struct CHDIR = 'winrt-app-type-revision' -print 'This test is not currently working on the bots: https://code.google.com/p/gyp/issues/detail?id=466' +print('This test is not currently working on the bots: https://code.google.com/p/gyp/issues/detail?id=466') sys.exit(0) if (sys.platform == 'win32' and diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-target-platform-version.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-target-platform-version.py index cd9244ed01..da29716d59 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-target-platform-version.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt-target-platform-version.py @@ -8,6 +8,7 @@ Make sure msvs_target_platform_version works correctly. """ +from __future__ import print_function import TestGyp import os @@ -16,7 +17,7 @@ import struct CHDIR = 'winrt-target-platform-version' -print 'This test is not currently working on the bots: https://code.google.com/p/gyp/issues/detail?id=466' +print('This test is not currently working on the bots: https://code.google.com/p/gyp/issues/detail?id=466') sys.exit(0) if (sys.platform == 'win32' and diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt.py index 283863ced7..67ccd5453e 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-enable-winrt.py @@ -8,6 +8,7 @@ Make sure msvs_enable_winrt works correctly. """ +from __future__ import print_function import TestGyp import os @@ -16,7 +17,7 @@ import struct CHDIR = 'enable-winrt' -print 'This test is not currently working on the bots: https://code.google.com/p/gyp/issues/detail?id=466' +print('This test is not currently working on the bots: https://code.google.com/p/gyp/issues/detail?id=466') sys.exit(0) if (sys.platform == 'win32' and diff --git a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-large-pdb.py b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-large-pdb.py index 4604745d14..f42d9d8b11 100644 --- a/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-large-pdb.py +++ b/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-large-pdb.py @@ -8,13 +8,14 @@ Make sure msvs_large_pdb works correctly. """ +from __future__ import print_function import TestGyp import struct import sys if sys.platform == 'win32': - print "This test is currently disabled: https://crbug.com/483696." + print("This test is currently disabled: https://crbug.com/483696.") sys.exit(0) @@ -37,8 +38,8 @@ def CheckImageAndPdb(test, image_basename, expected_page_size, pdb_file.seek(32, 0) page_size = struct.unpack('>f, 'options', options -print >>f, 'args', args +print('options', options, file=f) +print('args', args, file=f) f.close() diff --git a/media/webrtc/trunk/tools/gyp/tools/graphviz.py b/media/webrtc/trunk/tools/gyp/tools/graphviz.py index 326ae221cf..2f9a0fb171 100755 --- a/media/webrtc/trunk/tools/gyp/tools/graphviz.py +++ b/media/webrtc/trunk/tools/gyp/tools/graphviz.py @@ -50,9 +50,9 @@ def WriteGraph(edges): build_file, target_name, toolset = ParseTarget(src) files[build_file].append(src) - print 'digraph D {' - print ' fontsize=8' # Used by subgraphs. - print ' node [fontsize=8]' + print('digraph D {') + print(' fontsize=8') # Used by subgraphs. + print(' node [fontsize=8]') # Output nodes by file. We must first write out each node within # its file grouping before writing out any edges that may refer @@ -63,31 +63,31 @@ def WriteGraph(edges): # the display by making it a box without an internal node. target = targets[0] build_file, target_name, toolset = ParseTarget(target) - print ' "%s" [shape=box, label="%s\\n%s"]' % (target, filename, - target_name) + print(' "{}" [shape=box, label="{}\\n{}"]'.format(target, filename, + target_name)) else: # Group multiple nodes together in a subgraph. - print ' subgraph "cluster_%s" {' % filename - print ' label = "%s"' % filename + print(' subgraph "cluster_%s" {' % filename) + print(' label = "%s"' % filename) for target in targets: build_file, target_name, toolset = ParseTarget(target) - print ' "%s" [label="%s"]' % (target, target_name) - print ' }' + print(' "{}" [label="{}"]'.format(target, target_name)) + print(' }') # Now that we've placed all the nodes within subgraphs, output all # the edges between nodes. for src, dsts in edges.items(): for dst in dsts: - print ' "%s" -> "%s"' % (src, dst) + print(' "{}" -> "{}"'.format(src, dst)) - print '}' + print('}') def main(): if len(sys.argv) < 2: - print >>sys.stderr, __doc__ - print >>sys.stderr - print >>sys.stderr, 'usage: %s target1 target2...' % (sys.argv[0]) + print(__doc__, file=sys.stderr) + print(file=sys.stderr) + print('usage: %s target1 target2...' % (sys.argv[0]), file=sys.stderr) return 1 edges = LoadEdges('dump.json', sys.argv[1:]) diff --git a/media/webrtc/trunk/tools/gyp/tools/pretty_gyp.py b/media/webrtc/trunk/tools/gyp/tools/pretty_gyp.py index d5736bbd4a..b9eaa2c55d 100755 --- a/media/webrtc/trunk/tools/gyp/tools/pretty_gyp.py +++ b/media/webrtc/trunk/tools/gyp/tools/pretty_gyp.py @@ -32,7 +32,7 @@ def mask_comments(input): def quote_replace(matchobj): - return "%s%s%s%s" % (matchobj.group(1), + return "{}{}{}{}".format(matchobj.group(1), matchobj.group(2), 'x'*len(matchobj.group(3)), matchobj.group(2)) @@ -125,15 +125,15 @@ def prettyprint_input(lines): (brace_diff, after) = count_braces(line) if brace_diff != 0: if after: - print " " * (basic_offset * indent) + line + print(" " * (basic_offset * indent) + line) indent += brace_diff else: indent += brace_diff - print " " * (basic_offset * indent) + line + print(" " * (basic_offset * indent) + line) else: - print " " * (basic_offset * indent) + line + print(" " * (basic_offset * indent) + line) else: - print "" + print("") last_line = line diff --git a/media/webrtc/trunk/tools/gyp/tools/pretty_sln.py b/media/webrtc/trunk/tools/gyp/tools/pretty_sln.py index ca8cf4ad3f..b1f5bda357 100755 --- a/media/webrtc/trunk/tools/gyp/tools/pretty_sln.py +++ b/media/webrtc/trunk/tools/gyp/tools/pretty_sln.py @@ -26,7 +26,7 @@ def BuildProject(project, built, projects, deps): for dep in deps[project]: if dep not in built: BuildProject(dep, built, projects, deps) - print project + print(project) built.append(project) def ParseSolution(solution_file): @@ -100,44 +100,44 @@ def ParseSolution(solution_file): return (projects, dependencies) def PrintDependencies(projects, deps): - print "---------------------------------------" - print "Dependencies for all projects" - print "---------------------------------------" - print "-- --" + print("---------------------------------------") + print("Dependencies for all projects") + print("---------------------------------------") + print("-- --") for (project, dep_list) in sorted(deps.items()): - print "Project : %s" % project - print "Path : %s" % projects[project][0] + print("Project : %s" % project) + print("Path : %s" % projects[project][0]) if dep_list: for dep in dep_list: - print " - %s" % dep - print "" + print(" - %s" % dep) + print("") - print "-- --" + print("-- --") def PrintBuildOrder(projects, deps): - print "---------------------------------------" - print "Build order " - print "---------------------------------------" - print "-- --" + print("---------------------------------------") + print("Build order ") + print("---------------------------------------") + print("-- --") built = [] for (project, _) in sorted(deps.items()): if project not in built: BuildProject(project, built, projects, deps) - print "-- --" + print("-- --") def PrintVCProj(projects): for project in projects: - print "-------------------------------------" - print "-------------------------------------" - print project - print project - print project - print "-------------------------------------" - print "-------------------------------------" + print("-------------------------------------") + print("-------------------------------------") + print(project) + print(project) + print(project) + print("-------------------------------------") + print("-------------------------------------") project_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[1]), projects[project][2])) @@ -153,7 +153,7 @@ def PrintVCProj(projects): def main(): # check if we have exactly 1 parameter. if len(sys.argv) < 2: - print 'Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0] + print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0]) return 1 (projects, deps) = ParseSolution(sys.argv[1]) diff --git a/media/webrtc/trunk/tools/gyp/tools/pretty_vcproj.py b/media/webrtc/trunk/tools/gyp/tools/pretty_vcproj.py index 6099bd7cc4..1326b9c4b8 100755 --- a/media/webrtc/trunk/tools/gyp/tools/pretty_vcproj.py +++ b/media/webrtc/trunk/tools/gyp/tools/pretty_vcproj.py @@ -24,13 +24,13 @@ REPLACEMENTS = dict() ARGUMENTS = None -class CmpTuple(object): +class CmpTuple: """Compare function between 2 tuple.""" def __call__(self, x, y): return cmp(x[0], y[0]) -class CmpNode(object): +class CmpNode: """Compare function between 2 xml nodes.""" def __call__(self, x, y): @@ -61,7 +61,7 @@ class CmpNode(object): def PrettyPrintNode(node, indent=0): if node.nodeType == Node.TEXT_NODE: if node.data.strip(): - print '%s%s' % (' '*indent, node.data.strip()) + print('{}{}'.format(' '*indent, node.data.strip())) return if node.childNodes: @@ -73,23 +73,23 @@ def PrettyPrintNode(node, indent=0): # Print the main tag if attr_count == 0: - print '%s<%s>' % (' '*indent, node.nodeName) + print('{}<{}>'.format(' '*indent, node.nodeName)) else: - print '%s<%s' % (' '*indent, node.nodeName) + print('{}<{}'.format(' '*indent, node.nodeName)) all_attributes = [] for (name, value) in node.attributes.items(): all_attributes.append((name, value)) all_attributes.sort(CmpTuple()) for (name, value) in all_attributes: - print '%s %s="%s"' % (' '*indent, name, value) - print '%s>' % (' '*indent) + print('{} {}="{}"'.format(' '*indent, name, value)) + print('%s>' % (' '*indent)) if node.nodeValue: - print '%s %s' % (' '*indent, node.nodeValue) + print('{} {}'.format(' '*indent, node.nodeValue)) for sub_node in node.childNodes: PrettyPrintNode(sub_node, indent=indent+2) - print '%s' % (' '*indent, node.nodeName) + print('{}'.format(' '*indent, node.nodeName)) def FlattenFilter(node): @@ -283,7 +283,7 @@ def main(argv): # check if we have exactly 1 parameter. if len(argv) < 2: - print ('Usage: %s "c:\\path\\to\\vcproj.vcproj" [key1=value1] ' + print('Usage: %s "c:\\path\\to\\vcproj.vcproj" [key1=value1] ' '[key2=value2]' % argv[0]) return 1 diff --git a/media/webrtc/trunk/webrtc/PRESUBMIT.py b/media/webrtc/trunk/webrtc/PRESUBMIT.py index 4132c16874..825fc8e0be 100644 --- a/media/webrtc/trunk/webrtc/PRESUBMIT.py +++ b/media/webrtc/trunk/webrtc/PRESUBMIT.py @@ -10,7 +10,7 @@ def _LicenseHeader(input_api): """Returns the license header regexp.""" # Accept any year number from 2003 to the current year current_year = int(input_api.time.strftime('%Y')) - allowed_years = (str(s) for s in reversed(xrange(2003, current_year + 1))) + allowed_years = (str(s) for s in reversed(range(2003, current_year + 1))) years_re = '(' + '|'.join(allowed_years) + ')' license_header = ( r'.*? Copyright( \(c\))? %(year)s The WebRTC [Pp]roject [Aa]uthors\. ' diff --git a/media/webrtc/trunk/webrtc/build/extra_gitignore.py b/media/webrtc/trunk/webrtc/build/extra_gitignore.py index f8496686bb..536b83b1a0 100755 --- a/media/webrtc/trunk/webrtc/build/extra_gitignore.py +++ b/media/webrtc/trunk/webrtc/build/extra_gitignore.py @@ -28,7 +28,7 @@ def main(argv): modify_string = MODIFY_STRING % argv[0] gitignore_file = os.path.dirname(argv[0]) + '/../../.gitignore' - lines = open(gitignore_file, 'r').readlines() + lines = open(gitignore_file).readlines() for i, line in enumerate(lines): # Look for modify_string in the file to ensure we don't append the extra # patterns more than once. @@ -39,7 +39,7 @@ def main(argv): f = open(gitignore_file, 'w') f.write(''.join(lines)) - f.write(open(argv[1], 'r').read()) + f.write(open(argv[1]).read()) f.close() if __name__ == '__main__': diff --git a/media/webrtc/trunk/webrtc/build/gyp_webrtc.py b/media/webrtc/trunk/webrtc/build/gyp_webrtc.py index 87d8a57ddf..4335ccfd4d 100644 --- a/media/webrtc/trunk/webrtc/build/gyp_webrtc.py +++ b/media/webrtc/trunk/webrtc/build/gyp_webrtc.py @@ -21,4 +21,4 @@ import os path = os.path.abspath(os.path.split(__file__)[0]) -execfile(os.path.join(path, 'gyp_webrtc')) +exec(compile(open(os.path.join(path, 'gyp_webrtc'), "rb").read(), os.path.join(path, 'gyp_webrtc'), 'exec')) diff --git a/media/webrtc/trunk/webrtc/build/merge_libs.py b/media/webrtc/trunk/webrtc/build/merge_libs.py index 84904d61ce..4cd54f84d3 100644 --- a/media/webrtc/trunk/webrtc/build/merge_libs.py +++ b/media/webrtc/trunk/webrtc/build/merge_libs.py @@ -79,7 +79,7 @@ def main(argv): ' -exec', cmd, output_lib, '{} +']) else: cmd = ' '.join([cmd + output_lib] + FindFiles(search_path, pattern)) - print cmd + print(cmd) subprocess.check_call(cmd, shell=True) return 0 diff --git a/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py b/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py index b7b7ddd4a6..e85fcd66e3 100755 --- a/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py +++ b/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py @@ -48,15 +48,15 @@ def convert_yuv_to_png_files(yuv_file_name, yuv_frame_width, yuv_frame_height, % yuv_file_name, '-f', 'image2', '-vcodec', 'png', '%s' % output_files_pattern] try: - print 'Converting YUV file to PNG images (may take a while)...' - print ' '.join(command) + print('Converting YUV file to PNG images (may take a while)...') + print(' '.join(command)) helper_functions.run_shell_command( command, fail_msg='Error during YUV to PNG conversion') - except helper_functions.HelperError, err: - print 'Error executing command: %s. Error: %s' % (command, err) + except helper_functions.HelperError as err: + print('Error executing command: {}. Error: {}'.format(command, err)) return False except OSError: - print ('Did not find %s. Have you installed it?' % ffmpeg_path) + print('Did not find %s. Have you installed it?' % ffmpeg_path) return False return True @@ -82,7 +82,7 @@ def decode_frames(input_directory, zxing_path): """ if not zxing_path: zxing_path = 'zxing.exe' if sys.platform == 'win32' else 'zxing' - print 'Decoding barcodes from PNG files with %s...' % zxing_path + print('Decoding barcodes from PNG files with %s...' % zxing_path) return helper_functions.perform_action_on_all_files( directory=input_directory, file_pattern='frame_', file_extension='png', start_number=1, action=_decode_barcode_in_file, @@ -106,12 +106,12 @@ def _decode_barcode_in_file(file_name, command_line_decoder): text_file = open('%s.txt' % file_name[:-4], 'w') text_file.write(out) text_file.close() - except helper_functions.HelperError, err: - print 'Barcode in %s cannot be decoded.' % file_name - print err + except helper_functions.HelperError as err: + print('Barcode in %s cannot be decoded.' % file_name) + print(err) return False except OSError: - print ('Did not find %s. Have you installed it?' % command_line_decoder) + print('Did not find %s. Have you installed it?' % command_line_decoder) return False return True @@ -127,7 +127,7 @@ def _generate_stats_file(stats_file_name, input_directory='.'): file_prefix = os.path.join(input_directory, 'frame_') stats_file = open(stats_file_name, 'w') - print 'Generating stats file: %s' % stats_file_name + print('Generating stats file: %s' % stats_file_name) for i in range(1, _count_frames_in(input_directory=input_directory) + 1): frame_number = helper_functions.zero_pad(i) barcode_file_name = file_prefix + frame_number + '.txt' @@ -160,7 +160,7 @@ def _read_barcode_from_text_file(barcode_file_name): Return: (string): The decoded barcode. """ - barcode_file = open(barcode_file_name, 'r') + barcode_file = open(barcode_file_name) barcode = barcode_file.read() barcode_file.close() return barcode @@ -180,8 +180,8 @@ def _check_barcode(barcode): if len(barcode) != 12: return False - r1 = range(0, 11, 2) # Odd digits - r2 = range(1, 10, 2) # Even digits except last + r1 = list(range(0, 11, 2)) # Odd digits + r2 = list(range(1, 10, 2)) # Even digits except last dsum = 0 # Sum all the even digits for i in r1: @@ -272,19 +272,19 @@ def _main(): options.yuv_frame_height, output_directory=options.png_working_dir, ffmpeg_path=options.ffmpeg_path): - print 'An error occurred converting from YUV to PNG frames.' + print('An error occurred converting from YUV to PNG frames.') return -1 # Decode the barcodes from the PNG frames. if not decode_frames(input_directory=options.png_working_dir, zxing_path=options.zxing_path): - print 'An error occurred decoding barcodes from PNG frames.' + print('An error occurred decoding barcodes from PNG frames.') return -2 # Generate statistics file. _generate_stats_file(options.stats_file, input_directory=options.png_working_dir) - print 'Completed barcode decoding.' + print('Completed barcode decoding.') return 0 if __name__ == '__main__': diff --git a/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py b/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py index 3a8f35499d..937b64fc27 100755 --- a/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py +++ b/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py @@ -59,7 +59,7 @@ def generate_upca_barcodes(number_of_barcodes, barcode_width, barcode_height, helper_functions.run_shell_command( command, fail_msg=('Error during barcode %s generation' % content)) except helper_functions.HelperError as err: - print >> sys.stderr, err + print(err, file=sys.stderr) errors = True return not errors @@ -111,7 +111,7 @@ def _convert_to_yuv_and_delete(output_directory, file_name, pattern): file_name)) os.remove(file_name) except helper_functions.HelperError as err: - print >> sys.stderr, err + print(err, file=sys.stderr) return False return True @@ -154,7 +154,7 @@ def _add_to_file_and_delete(output_file, file_name): try: os.remove(file_name) except OSError as e: - print >> sys.stderr, 'Error deleting file %s.\nError: %s' % (file_name, e) + print('Error deleting file {}.\nError: {}'.format(file_name, e), file=sys.stderr) return False return True diff --git a/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py b/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py index 466bd50fd9..35080879b1 100755 --- a/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py +++ b/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py @@ -25,11 +25,11 @@ def run_ant_build_command(path_to_ant_build_file): process = subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr) process.wait() if process.returncode != 0: - print >> sys.stderr, 'Failed to execute: %s' % ' '.join(cmd) + print('Failed to execute: %s' % ' '.join(cmd), file=sys.stderr) return process.returncode except subprocess.CalledProcessError as e: - print >> sys.stderr, 'Failed to execute: %s.\nCause: %s' % (' '.join(cmd), - e) + print('Failed to execute: {}.\nCause: {}'.format(' '.join(cmd), + e), file=sys.stderr) return -1 def _main(): diff --git a/media/webrtc/trunk/webrtc/tools/barcode_tools/helper_functions.py b/media/webrtc/trunk/webrtc/tools/barcode_tools/helper_functions.py index bb0b167334..75702fb375 100644 --- a/media/webrtc/trunk/webrtc/tools/barcode_tools/helper_functions.py +++ b/media/webrtc/trunk/webrtc/tools/barcode_tools/helper_functions.py @@ -52,7 +52,7 @@ def run_shell_command(cmd_list, fail_msg=None): output, error = process.communicate() if process.returncode != 0: if fail_msg: - print >> sys.stderr, fail_msg + print(fail_msg, file=sys.stderr) raise HelperError('Failed to run %s: command returned %d and printed ' '%s and %s' % (' '.join(cmd_list), process.returncode, output, error)) diff --git a/media/webrtc/trunk/webrtc/tools/compare_videos.py b/media/webrtc/trunk/webrtc/tools/compare_videos.py index f6275a67d3..b5167cdc03 100755 --- a/media/webrtc/trunk/webrtc/tools/compare_videos.py +++ b/media/webrtc/trunk/webrtc/tools/compare_videos.py @@ -99,7 +99,7 @@ def main(): # On Windows, sometimes the inherited stdin handle from the parent process # fails. Work around this by passing null to stdin to the subprocesses. - null_filehandle = open(os.devnull, 'r') + null_filehandle = open(os.devnull) # Run barcode decoder on the test video to identify frame numbers. png_working_directory = tempfile.mkdtemp() @@ -122,7 +122,7 @@ def main(): shutil.rmtree(png_working_directory) if barcode_decoder.returncode != 0: - print 'Failed to run barcode decoder script.' + print('Failed to run barcode decoder script.') return 1 # Run frame analyzer to compare the videos and print output. @@ -139,7 +139,7 @@ def main(): stdout=sys.stdout, stderr=sys.stderr) frame_analyzer.wait() if frame_analyzer.returncode != 0: - print 'Failed to run frame analyzer.' + print('Failed to run frame analyzer.') return 1 return 0 diff --git a/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/perf/perf_utils.py b/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/perf/perf_utils.py index 77eda1e7a3..82b4f0c7f2 100644 --- a/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/perf/perf_utils.py +++ b/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/perf/perf_utils.py @@ -25,7 +25,7 @@ def PrintPerfResult(graph_name, series_name, data_point, units, this test on the waterfall page, not the stdio page). """ waterfall_indicator = ['', '*'][show_on_waterfall] - print '%sRESULT %s: %s= %s %s' % ( + print('{}RESULT {}: {}= {} {}'.format( waterfall_indicator, graph_name, series_name, - str(data_point).replace(' ', ''), units) + str(data_point).replace(' ', ''), units)) sys.stdout.flush() \ No newline at end of file diff --git a/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/run_audio_test.py b/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/run_audio_test.py index 51caa42cd9..52f42cf943 100755 --- a/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/run_audio_test.py +++ b/media/webrtc/trunk/webrtc/tools/e2e_quality/audio/run_audio_test.py @@ -52,7 +52,7 @@ def main(argv): # Get the initial default capture device, to restore later. command = ['pacmd', 'list-sources'] - print ' '.join(command) + print(' '.join(command)) proc = subprocess.Popen(command, stdout=subprocess.PIPE) output = proc.communicate()[0] if proc.returncode != 0: @@ -67,14 +67,14 @@ def main(argv): # We pass the render device for VoiceEngine to select because (for unknown # reasons) the virtual device is sometimes not used when the default. command = ['pacmd', 'set-default-source', options.play_sink + '.monitor'] - print ' '.join(command) + print(' '.join(command)) retcode = subprocess.call(command, stdout=subprocess.PIPE) if retcode != 0: return retcode command = [options.harness, '--render=' + options.rec_sink, '--codec=' + options.codec, '--rate=' + options.rate] - print ' '.join(command) + print(' '.join(command)) voe_proc = subprocess.Popen(command) # If recording starts before there is data available, pacat sometimes @@ -87,12 +87,12 @@ def main(argv): '--channels=' + options.channels, '--raw'] command = (['pacat', '-p', '-d', options.play_sink] + format_args + [options.input]) - print ' '.join(command) + print(' '.join(command)) play_proc = subprocess.Popen(command) command = (['pacat', '-r', '-d', options.rec_sink + '.monitor'] + format_args + [options.output]) - print ' '.join(command) + print(' '.join(command)) record_proc = subprocess.Popen(command) retcode = play_proc.wait() @@ -104,14 +104,14 @@ def main(argv): # Restore the initial default capture device. command = ['pacmd', 'set-default-source', default_source] - print ' '.join(command) + print(' '.join(command)) retcode = subprocess.call(command, stdout=subprocess.PIPE) if retcode != 0: return retcode if options.compare and options.regexp: command = shlex.split(options.compare) + [options.input, options.output] - print ' '.join(command) + print(' '.join(command)) proc = subprocess.Popen(command, stdout=subprocess.PIPE) output = proc.communicate()[0] if proc.returncode != 0: diff --git a/netwerk/dns/prepare_tlds.py b/netwerk/dns/prepare_tlds.py index a97b20948c..4e05530e9c 100644 --- a/netwerk/dns/prepare_tlds.py +++ b/netwerk/dns/prepare_tlds.py @@ -50,7 +50,10 @@ def _normalizeHostname(domain): def convertLabel(label): if _isASCII(label): return label.lower() - return encodings.idna.ToASCII(label) + result = encodings.idna.ToASCII(label) + if isinstance(result, bytes): + result = result.decode('ascii') + return result return ".".join(map(convertLabel, domain.split("."))) def _isASCII(s): diff --git a/nsprpub/automation/release/nspr-release-helper.py b/nsprpub/automation/release/nspr-release-helper.py index f62b80404a..0199fc48e2 100644 --- a/nsprpub/automation/release/nspr-release-helper.py +++ b/nsprpub/automation/release/nspr-release-helper.py @@ -4,6 +4,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import print_function import os import sys import datetime @@ -17,7 +18,7 @@ f_conf = "configure" f_conf_in = "configure.in" def check_call_noisy(cmd, *args, **kwargs): - print("Executing command:", cmd) + print(("Executing command:", cmd)) check_call(cmd, *args, **kwargs) o = OptionParser(usage="client.py [options] remove_beta | set_beta | print_library_versions | set_version_to_minor_release | set_version_to_patch_release | create_nspr_release_archive") @@ -30,7 +31,7 @@ except IndexError: sys.exit(2) def exit_with_failure(what): - print("failure: ", what) + print(("failure: ", what)) sys.exit(2) def check_files_exist(): @@ -144,12 +145,12 @@ def create_nspr_release_archive(): check_call_noisy(["mkdir", "-p", nspr_stagedir]) check_call_noisy(["hg", "archive", "-r", nsprreltag, "--prefix=nspr-" + nsprrel + "/nspr", "../stage/v" + nsprrel + "/src/" + nspr_tar, "-X", ".hgtags"]) - print("changing to directory " + nspr_stagedir) + print(("changing to directory " + nspr_stagedir)) os.chdir(nspr_stagedir) check_call("sha1sum " + nspr_tar + " > SHA1SUMS", shell=True) check_call("sha256sum " + nspr_tar + " > SHA256SUMS", shell=True) - print("created directory " + nspr_stagedir + " with files:") + print(("created directory " + nspr_stagedir + " with files:")) check_call_noisy(["ls", "-l"]) if action in ('remove_beta'): diff --git a/nsprpub/build/win32/pgomerge.py b/nsprpub/build/win32/pgomerge.py index 313d66870d..cbc9dbe672 100644 --- a/nsprpub/build/win32/pgomerge.py +++ b/nsprpub/build/win32/pgomerge.py @@ -8,6 +8,7 @@ # $PWD/$basename.pgd using pgomgr, then deletes them. # No errors if any of these files don't exist. +from __future__ import print_function import sys, os, os.path, subprocess if not sys.platform == "win32": raise Exception("This script was only meant for Windows.") @@ -39,6 +40,6 @@ def MergePGOFiles(basename, pgddir, pgcdir): if __name__ == '__main__': if len(sys.argv) != 3: - print >>sys.stderr, "Usage: pgomerge.py " + print("Usage: pgomerge.py ", file=sys.stderr) sys.exit(1) MergePGOFiles(sys.argv[1], os.getcwd(), sys.argv[2]) diff --git a/old-configure.in b/old-configure.in index ad404f2051..5049804f57 100644 --- a/old-configure.in +++ b/old-configure.in @@ -3637,7 +3637,7 @@ if test -f "${srcdir}/${MOZ_BUILD_APP}/configure.in" ; then _subconfigure_subdir="$1" _subconfigure_config_args="$ac_configure_args" } - tmpscript=`$PYTHON -c 'import os, tempfile; print tempfile.mktemp(prefix="subscript.").replace(os.sep, "/")'` || exit 1 + tmpscript=`$PYTHON -c 'import os, tempfile; print(tempfile.mktemp(prefix="subscript.").replace(os.sep, "/"))'` || exit 1 ${TOOLCHAIN_PREFIX}m4 "${srcdir}/build/autoconf/subconfigure.m4" \ "${srcdir}/build/autoconf/altoptions.m4" \ "${srcdir}/${MOZ_BUILD_APP}/configure.in" > $tmpscript diff --git a/other-licenses/ply/ply/lex.py b/other-licenses/ply/ply/lex.py index 267ec100fc..6885ed6736 100644 --- a/other-licenses/ply/ply/lex.py +++ b/other-licenses/ply/ply/lex.py @@ -39,7 +39,7 @@ import re, sys, types, copy, os # This tuple contains known string types try: # Python 2.6 - StringTypes = (types.StringType, types.UnicodeType) + StringTypes = (bytes, str) except AttributeError: # Python 3.0 StringTypes = (str, bytes) @@ -49,7 +49,7 @@ except AttributeError: if sys.version_info[0] < 3: def func_code(f): - return f.func_code + return f.__code__ else: def func_code(f): return f.__code__ @@ -177,7 +177,7 @@ class Lexer: tf.write("# %s.py. This file automatically created by PLY (version %s). Don't edit!\n" % (tabfile,__version__)) tf.write("_tabversion = %s\n" % repr(__version__)) tf.write("_lextokens = %s\n" % repr(self.lextokens)) - tf.write("_lexreflags = %s\n" % repr(self.lexreflags)) + tf.write("_lexreflags = %d\n" % int(self.lexreflags)) tf.write("_lexliterals = %s\n" % repr(self.lexliterals)) tf.write("_lexstateinfo = %s\n" % repr(self.lexstateinfo)) @@ -505,6 +505,8 @@ def _form_master_re(relist,reflags,ldict,toknames): except Exception: m = int(len(relist)/2) if m == 0: m = 1 + if m >= len(relist): + raise llist, lre, lnames = _form_master_re(relist[:m],reflags,ldict,toknames) rlist, rre, rnames = _form_master_re(relist[m:],reflags,ldict,toknames) return llist+rlist, lre+rre, lnames+rnames diff --git a/other-licenses/ply/ply/yacc.py b/other-licenses/ply/ply/yacc.py index e9f5c65755..a7038f8ed6 100644 --- a/other-licenses/ply/ply/yacc.py +++ b/other-licenses/ply/ply/yacc.py @@ -89,21 +89,21 @@ import re, types, sys, os.path # Compatibility function for python 2.6/3.0 if sys.version_info[0] < 3: def func_code(f): - return f.func_code + return f.__code__ else: def func_code(f): return f.__code__ # Compatibility try: - MAXINT = sys.maxint + MAXINT = sys.maxsize except AttributeError: MAXINT = sys.maxsize # Python 2.x/3.0 compatibility. def load_ply_lex(): if sys.version_info[0] < 3: - import lex + from . import lex else: import ply.lex as lex return lex @@ -1844,7 +1844,7 @@ class LRTable(object): def read_pickle(self,filename): try: - import cPickle as pickle + import six.moves.cPickle as pickle except ImportError: import pickle @@ -2665,7 +2665,7 @@ del _lr_goto_items def pickle_table(self,filename,signature=""): try: - import cPickle as pickle + import six.moves.cPickle as pickle except ImportError: import pickle outf = open(filename,"wb") diff --git a/parser/html/java/htmlparser/generate-encoding-data.py b/parser/html/java/htmlparser/generate-encoding-data.py index 69b2fdc309..8466dd2e05 100644 --- a/parser/html/java/htmlparser/generate-encoding-data.py +++ b/parser/html/java/htmlparser/generate-encoding-data.py @@ -608,16 +608,16 @@ final class Big5Data { bits = [] for (low, high) in astral_ranges: - for i in xrange(low, high): + for i in range(low, high): bits.append(1 if index[i] > 0xFFFF else 0) # pad length to multiple of 16 -for j in xrange(16 - (len(bits) % 16)): +for j in range(16 - (len(bits) % 16)): bits.append(0) i = 0 while i < len(bits): accu = 0 - for j in xrange(16): + for j in range(16): accu |= bits[i + j] << j if accu == 0x22: class_file.write('\\"') @@ -632,7 +632,7 @@ class_file.write('''"; j = 0 for (low, high) in ranges: class_file.write(''' private static final String TABLE%d = "''' % j) - for i in xrange(low, high): + for i in range(low, high): class_file.write('\\u%04X' % (index[i] & 0xFFFF)) class_file.write('''"; @@ -704,7 +704,7 @@ prefer_last = [ for code_point in prefer_last: # Python lists don't have .rindex() :-( - for i in xrange(len(index) - 1, -1, -1): + for i in range(len(index) - 1, -1, -1): candidate = index[i] if candidate == code_point: class_file.write(''' case 0x%04X: diff --git a/python/PyECC/ecc/Key.py b/python/PyECC/ecc/Key.py index 8ba2685768..998e03f610 100644 --- a/python/PyECC/ecc/Key.py +++ b/python/PyECC/ecc/Key.py @@ -168,11 +168,12 @@ prime having great security characteristics, 521 bits are preferred over a constructed 512 bit field.) """ -from encoding import * -from eccrypt import * -import ecdsa +from __future__ import print_function +from .encoding import * +from .eccrypt import * +from . import ecdsa import hashlib -from SecurityViolationException import * +from .SecurityViolationException import * class Key: @@ -214,7 +215,7 @@ class Key: if kid == k.keyid(): return k else: - raise ValueError, "Invalid Key ID" + raise ValueError("Invalid Key ID") # --- IDENTIFICATION AND VALIDATION ---------------------------------------- @@ -259,7 +260,7 @@ class Key: s = ecdsa.sign(h, self._priv) return enc_point(s) else: - raise AttributeError, "Private key needed for signing." + raise AttributeError("Private key needed for signing.") def verify(self, data, sig, hashfunc = 'sha256'): '''Verify the signature of data using the specified hash function''' @@ -294,7 +295,7 @@ class Key: if source.verify(text, sgn): return text else: - raise SecurityViolationException, "Invalid Signature" + raise SecurityViolationException("Invalid Signature") if __name__ == "__main__": @@ -302,7 +303,7 @@ if __name__ == "__main__": import time def test_overhead(): - print "sender", "receiver", "+bytes", "+enctime", "+dectime" + print(("sender", "receiver", "+bytes", "+enctime", "+dectime")) for s in [192, 224, 256, 384, 521]: sender = Key.generate(s) for r in [192, 224, 256, 384, 521]: @@ -313,7 +314,7 @@ if __name__ == "__main__": t = time.time() receiver.auth_decrypt(e, sender) t2 = time.time() - t - print s, r, len(e), t1, t2 + print((s, r, len(e), t1, t2)) diff --git a/python/PyECC/ecc/Rabbit.py b/python/PyECC/ecc/Rabbit.py index 209f01e1ee..09a4a4994e 100644 --- a/python/PyECC/ecc/Rabbit.py +++ b/python/PyECC/ecc/Rabbit.py @@ -31,17 +31,17 @@ class Rabbit: key = '\x00' * (16 - len(key)) + key # if len(key) > 16 bytes only the first 16 will be considered k = [ord(key[i + 1]) | (ord(key[i]) << 8) - for i in xrange(14, -1, -2)] + for i in range(14, -1, -2)] else: # k[0] = least significant 16 bits # k[7] = most significant 16 bits - k = [(key >> i) & 0xFFFF for i in xrange(0, 128, 16)] + k = [(key >> i) & 0xFFFF for i in range(0, 128, 16)] # State and counter initialization x = [(k[(j + 5) % 8] << 16) | k[(j + 4) % 8] if j & 1 else - (k[(j + 1) % 8] << 16) | k[j] for j in xrange(8)] + (k[(j + 1) % 8] << 16) | k[j] for j in range(8)] c = [(k[j] << 16) | k[(j + 1) % 8] if j & 1 else - (k[(j + 4) % 8] << 16) | k[(j + 5) % 8] for j in xrange(8)] + (k[(j + 4) % 8] << 16) | k[(j + 5) % 8] for j in range(8)] self.x = x self.c = c @@ -49,12 +49,12 @@ class Rabbit: self._buf = 0 # output buffer self._buf_bytes = 0 # fill level of buffer - self.next() - self.next() - self.next() - self.next() + next(self) + next(self) + next(self) + next(self) - for j in xrange(8): + for j in range(8): c[j] ^= x[(j + 4) % 8] self.start_x = self.x[:] # backup initial key for IV/reset @@ -99,10 +99,10 @@ class Rabbit: c[6] ^= i2 c[7] ^= i3 - self.next() - self.next() - self.next() - self.next() + next(self) + next(self) + next(self) + next(self) def next(self): @@ -130,7 +130,7 @@ class Rabbit: c[7] = t % WORDSIZE b = t // WORDSIZE - g = [_nsf(x[j], c[j]) for j in xrange(8)] + g = [_nsf(x[j], c[j]) for j in range(8)] x[0] = (g[0] + rot16(g[7]) + rot16(g[6])) % WORDSIZE x[1] = (g[1] + rot08(g[0]) + g[7]) % WORDSIZE @@ -168,7 +168,7 @@ class Rabbit: next = self.next derive = self.derive - for i in xrange(n): + for i in range(n): if not j: j = 16 next() diff --git a/python/PyECC/ecc/curves.py b/python/PyECC/ecc/curves.py index ee5847fc50..ecbcb55362 100644 --- a/python/PyECC/ecc/curves.py +++ b/python/PyECC/ecc/curves.py @@ -16,35 +16,35 @@ obfuscate non-critical transmissions. # (see FIPS 186-3, Appendix D.1.2) DOMAINS = { # Bits : (p, order of E(GF(P)), parameter b, base point x, base point y) - 192 : (0xfffffffffffffffffffffffffffffffeffffffffffffffffL, - 0xffffffffffffffffffffffff99def836146bc9b1b4d22831L, - 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1L, - 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012L, - 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811L), + 192 : (0xfffffffffffffffffffffffffffffffeffffffffffffffff, + 0xffffffffffffffffffffffff99def836146bc9b1b4d22831, + 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1, + 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012, + 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811), - 224 : (0xffffffffffffffffffffffffffffffff000000000000000000000001L, - 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3dL, - 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4L, - 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21L, - 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34L), + 224 : (0xffffffffffffffffffffffffffffffff000000000000000000000001, + 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d, + 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4, + 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21, + 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34), - 256 : (0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffL, - 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551L, - 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bL, - 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296L, - 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5L), + 256 : (0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff, + 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551, + 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b, + 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, + 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5), - 384 : (0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffL, - 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973L, - 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aefL, - 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7L, - 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5fL), + 384 : (0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973, + 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef, + 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7, + 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f), - 521 : (0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffL, - 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409L, - 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00L, - 0x0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66L, - 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650L) + 521 : (0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409, + 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00, + 0x0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66, + 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650) } @@ -52,17 +52,17 @@ DOMAINS = { # (not intended for use in signing, hence the missing group order) DOMAINS.update({ - 128 : (0xffffffffffffffffffffffffffffff61L, + 128 : (0xffffffffffffffffffffffffffffff61, None, - 0xd83d3eb8266a89927d73d5fe263d5f23L, - 0xa94d2d8531f7af8bde367def12b98eadL, - 0x9f44e1d671beb68fd2df7f877ab13fa6L), + 0xd83d3eb8266a89927d73d5fe263d5f23, + 0xa94d2d8531f7af8bde367def12b98ead, + 0x9f44e1d671beb68fd2df7f877ab13fa6), - 160 : (0xffffffffffffffffffffffffffffffffffffffd1L, + 160 : (0xffffffffffffffffffffffffffffffffffffffd1, None, - 0x94bfe70deef7b94742c089ca4db3ca27fbe1f754L, - 0xcc6562c2969ac57524b8d0f300d1f598c908c121L, - 0x952ddde80a252683dd7ba90fb5919899b5af69f5L) + 0x94bfe70deef7b94742c089ca4db3ca27fbe1f754, + 0xcc6562c2969ac57524b8d0f300d1f598c908c121, + 0x952ddde80a252683dd7ba90fb5919899b5af69f5) }) CURVE_P = 3 # global parameter of all curves (for efficiency reasons) @@ -75,7 +75,7 @@ def get_curve(bits): p, n, b, x, y = DOMAINS[bits] return bits, p, n, CURVE_P, p - b, (x, y) else: - raise KeyError, "Key size not implemented: %s" % bits + raise KeyError("Key size not implemented: %s" % bits) def implemented_keys(must_sign = False): return [k for k in DOMAINS if not must_sign or DOMAINS[k][1]] diff --git a/python/PyECC/ecc/eccrypt.py b/python/PyECC/ecc/eccrypt.py index c38876d071..c9fadee46a 100644 --- a/python/PyECC/ecc/eccrypt.py +++ b/python/PyECC/ecc/eccrypt.py @@ -3,11 +3,11 @@ # COPYRIGHT (c) 2010 by Toni Mattis # -from curves import get_curve -from elliptic import mulp -from encoding import enc_long +from .curves import get_curve +from .elliptic import mulp +from .encoding import enc_long from random import SystemRandom -from Rabbit import Rabbit +from .Rabbit import Rabbit # important for cryptographically secure random numbers: random = SystemRandom() @@ -31,9 +31,9 @@ def encrypt(message, qk, encrypter = Rabbit): try: bits, cn, n, cp, cq, g = get_curve(bits) if not n: - raise ValueError, "Key size %s not suitable for encryption" % bits + raise ValueError("Key size %s not suitable for encryption" % bits) except KeyError: - raise ValueError, "Key size %s not implemented" % bits + raise ValueError("Key size %s not implemented" % bits) k = random.randint(1, n - 1) # temporary private key k kg = mulp(cp, cq, cn, g, k) # temporary public key k*G @@ -57,7 +57,7 @@ def decrypt(message, kg, dk, decrypter = Rabbit): try: bits, cn, n, cp, cq, g = get_curve(bits) except KeyError: - raise ValueError, "Key size %s not implemented" % bits + raise ValueError("Key size %s not implemented" % bits) sg = mulp(cp, cq, cn, kg, d) # shared secret d*(k*G) = k*d*G return decrypter(enc_long(sg[0])).decrypt(message) diff --git a/python/PyECC/ecc/ecdsa.py b/python/PyECC/ecc/ecdsa.py index 6b52aeaa5d..b558ebd58d 100644 --- a/python/PyECC/ecc/ecdsa.py +++ b/python/PyECC/ecc/ecdsa.py @@ -4,8 +4,8 @@ # COPYRIGHT (c) 2010 by Toni Mattis # -from elliptic import inv, mulf, mulp, muladdp, element -from curves import get_curve, implemented_keys +from .elliptic import inv, mulf, mulp, muladdp, element +from .curves import get_curve, implemented_keys from os import urandom import hashlib @@ -23,13 +23,13 @@ def keypair(bits): try: bits, cn, n, cp, cq, g = get_curve(bits) except KeyError: - raise ValueError, "Key size %s not implemented" % bits + raise ValueError("Key size %s not implemented" % bits) if n > 0: d = randkey(bits, n) q = mulp(cp, cq, cn, g, d) return (bits, q), (bits, d) else: - raise ValueError, "Key size %s not suitable for signing" % bits + raise ValueError("Key size %s not suitable for signing" % bits) def supported_keys(): '''Return a list of all key sizes implemented for signing''' @@ -134,17 +134,17 @@ if __name__ == "__main__": d = get_curve(bits) t = time.time() - for i in xrange(rounds): + for i in range(rounds): qk, dk = keypair(bits) tgen = time.time() - t t = time.time() - for i in xrange(rounds): + for i in range(rounds): s = sign(0, dk) tsign = time.time() - t t = time.time() - for i in xrange(rounds): + for i in range(rounds): verify(0, s, qk) tver = time.time() - t diff --git a/python/PyECC/ecc/elliptic.py b/python/PyECC/ecc/elliptic.py index 9191a88488..0133a308e5 100644 --- a/python/PyECC/ecc/elliptic.py +++ b/python/PyECC/ecc/elliptic.py @@ -1,4 +1,3 @@ - # --- ELLIPTIC CURVE MATH ------------------------------------------------------ # # curve definition: y^2 = x^3 - p*x - q @@ -360,9 +359,9 @@ if __name__ == "__main__": q = curve_q(p1[0], p1[1], p, n) p2 = mulp(p, q, n, p1, rsa.random.randint(1, n)) - c1 = [rsa.random.randint(1, n) for i in xrange(tcount)] - c2 = [rsa.random.randint(1, n) for i in xrange(tcount)] - c = zip(c1, c2) + c1 = [rsa.random.randint(1, n) for i in range(tcount)] + c2 = [rsa.random.randint(1, n) for i in range(tcount)] + c = list(zip(c1, c2)) t = time.time() for i, j in c: diff --git a/python/PyECC/ecc/encoding.py b/python/PyECC/ecc/encoding.py index 24d3eb5a89..4b474295ae 100644 --- a/python/PyECC/ecc/encoding.py +++ b/python/PyECC/ecc/encoding.py @@ -158,7 +158,7 @@ class Decoder: self._parent._res.append(self._res) return self._parent else: - raise RuntimeError, "Cannont exit top level Decoder" + raise RuntimeError("Cannont exit top level Decoder") def continues(self): return (not self._limit) or (self._io.tell() < self._limit) diff --git a/python/PyECC/ecc/performance.py b/python/PyECC/ecc/performance.py index 724176aef8..55787868d4 100644 --- a/python/PyECC/ecc/performance.py +++ b/python/PyECC/ecc/performance.py @@ -36,13 +36,11 @@ def test_verification_perf(n = 100): return results def print_dict(title, d): - print title - print '-' * len(title) + print(title) + print('-' * len(title)) for k, v in d.items(): - print k, '\t', v - print - -n = 100 + print(k, '\t', v) + print(n = 100) print_dict("Key generation", test_generation_perf(n)) print_dict("Signing", test_signing_perf(n)) print_dict("Verifying", test_verification_perf(n)) diff --git a/python/PyECC/ecc/primes.py b/python/PyECC/ecc/primes.py index a8bc1424bf..7e2cb7953c 100644 --- a/python/PyECC/ecc/primes.py +++ b/python/PyECC/ecc/primes.py @@ -33,14 +33,14 @@ def prime(n, k): s += 1 d /= 2 - for i in xrange(k): + for i in range(k): - a = long(2 + random.randint(0, n - 4)) + a = int(2 + random.randint(0, n - 4)) x = exp(a, d, n) if (x == 1) or (x == n - 1): continue - for r in xrange(1, s): + for r in range(1, s): x = (x * x) % n if x == 1: diff --git a/python/PyECC/ecc/shacrypt.py b/python/PyECC/ecc/shacrypt.py index 69ee7b9433..d637bcb7d2 100644 --- a/python/PyECC/ecc/shacrypt.py +++ b/python/PyECC/ecc/shacrypt.py @@ -17,7 +17,7 @@ BPOS = tuple(range(64)) def enc_block(block, key, rounds = 16): x = block[:64] y = block[64:] - for i in xrange(rounds): + for i in range(rounds): h = sha512(x + key).digest() y = ''.join([chr(ord(y[k]) ^ ord(h[k])) for k in BPOS]) h = sha512(y + key).digest() @@ -27,7 +27,7 @@ def enc_block(block, key, rounds = 16): def dec_block(block, key, rounds = 16): x = block[:64] y = block[64:] - for i in xrange(rounds): + for i in range(rounds): h = sha512(y + key).digest() x = ''.join([chr(ord(x[k]) ^ ord(h[k])) for k in BPOS]) h = sha512(x + key).digest() diff --git a/python/altgraph/altgraph/Dot.py b/python/altgraph/altgraph/Dot.py index 49a471e4da..4629376283 100644 --- a/python/altgraph/altgraph/Dot.py +++ b/python/altgraph/altgraph/Dot.py @@ -108,7 +108,7 @@ import warnings from altgraph import GraphError -class Dot(object): +class Dot: ''' A class providing a **graphviz** (dot language) representation allowing a fine grained control over how the graph is being @@ -180,12 +180,12 @@ class Dot(object): if mode == 'neato': self.save_dot(self.temp_neo) - neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo) + neato_cmd = "{} -o {} {}".format(self.neato, self.temp_dot, self.temp_neo) os.system(neato_cmd) else: self.save_dot(self.temp_dot) - plot_cmd = "%s %s" % (self.dotty, self.temp_dot) + plot_cmd = "{} {}".format(self.dotty, self.temp_dot) os.system(plot_cmd) def node_style(self, node, **kwargs): @@ -208,28 +208,28 @@ class Dot(object): Modifies an edge style to the dot representation. ''' if tail not in self.nodes: - raise GraphError("invalid node %s" % (tail,)) + raise GraphError("invalid node {}".format(tail)) try: if tail not in self.edges[head]: self.edges[head][tail]= {} self.edges[head][tail] = kwargs except KeyError: - raise GraphError("invalid edge %s -> %s " % (head, tail) ) + raise GraphError("invalid edge {} -> {} ".format(head, tail) ) def iterdot(self): # write graph title if self.type == 'digraph': - yield 'digraph %s {\n' % (self.name,) + yield 'digraph {} {{\n'.format(self.name) elif self.type == 'graph': - yield 'graph %s {\n' % (self.name,) + yield 'graph {} {{\n'.format(self.name) else: - raise GraphError("unsupported graphtype %s" % (self.type,)) + raise GraphError("unsupported graphtype {}".format(self.type)) # write overall graph attributes for attr_name, attr_value in sorted(self.attr.items()): - yield '%s="%s";' % (attr_name, attr_value) + yield '{}="{}";'.format(attr_name, attr_value) yield '\n' # some reusable patterns @@ -238,7 +238,7 @@ class Dot(object): # write node attributes for node_name, node_attr in sorted(self.nodes.items()): - yield '\t"%s" [' % (node_name,) + yield '\t"{}" ['.format(node_name) for attr_name, attr_value in sorted(node_attr.items()): yield cpatt % (attr_name, attr_value) yield epatt @@ -247,9 +247,9 @@ class Dot(object): for head in sorted(self.edges): for tail in sorted(self.edges[head]): if self.type == 'digraph': - yield '\t"%s" -> "%s" [' % (head, tail) + yield '\t"{}" -> "{}" ['.format(head, tail) else: - yield '\t"%s" -- "%s" [' % (head, tail) + yield '\t"{}" -- "{}" ['.format(head, tail) for attr_name, attr_value in sorted(self.edges[head][tail].items()): yield cpatt % (attr_name, attr_value) yield epatt @@ -287,13 +287,13 @@ class Dot(object): if mode == 'neato': self.save_dot(self.temp_neo) - neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo) + neato_cmd = "{} -o {} {}".format(self.neato, self.temp_dot, self.temp_neo) os.system(neato_cmd) plot_cmd = self.dot else: self.save_dot(self.temp_dot) plot_cmd = self.dot - file_name = "%s.%s" % (file_name, file_type) - create_cmd = "%s -T%s %s -o %s" % (plot_cmd, file_type, self.temp_dot, file_name) + file_name = "{}.{}".format(file_name, file_type) + create_cmd = "{} -T{} {} -o {}".format(plot_cmd, file_type, self.temp_dot, file_name) os.system(create_cmd) diff --git a/python/altgraph/altgraph/Graph.py b/python/altgraph/altgraph/Graph.py index 491e5c2287..fc619e4e07 100644 --- a/python/altgraph/altgraph/Graph.py +++ b/python/altgraph/altgraph/Graph.py @@ -16,7 +16,7 @@ altgraph.Graph - Base Graph class from altgraph import GraphError from collections import deque -class Graph(object): +class Graph: """ The Graph class represents a directed graph with *N* nodes and *E* edges. @@ -110,7 +110,7 @@ class Graph(object): self.nodes[tail_id][0].append(edge) self.nodes[head_id][1].append(edge) except KeyError: - raise GraphError('Invalid nodes %s -> %s' % (head_id, tail_id)) + raise GraphError('Invalid nodes {} -> {}'.format(head_id, tail_id)) # store edge information self.edges[edge] = (head_id, tail_id, edge_data) @@ -491,7 +491,7 @@ class Graph(object): The forward parameter specifies whether it is a forward or backward traversal. """ - visited, stack = set([start]), deque([start]) + visited, stack = {start}, deque([start]) if forward: get_edges = self.out_edges @@ -518,7 +518,7 @@ class Graph(object): condition callback is only called when node_data is not None. """ - visited, stack = set([start]), deque([start]) + visited, stack = {start}, deque([start]) if forward: get_edges = self.out_edges @@ -550,7 +550,7 @@ class Graph(object): traversal. Returns a list of tuples where the first value is the hop value the second value is the node id. """ - queue, visited = deque([(start, 0)]), set([start]) + queue, visited = deque([(start, 0)]), {start} # the direction of the bfs depends on the edges that are sampled if forward: diff --git a/python/altgraph/altgraph/GraphAlgo.py b/python/altgraph/altgraph/GraphAlgo.py index 9e6fff2b17..2cd4a4ee18 100644 --- a/python/altgraph/altgraph/GraphAlgo.py +++ b/python/altgraph/altgraph/GraphAlgo.py @@ -127,7 +127,7 @@ class _priorityDictionary(dict): dict.__setitem__(self,key,val) heap = self.__heap if len(heap) > 2 * len(self): - self.__heap = [(v,k) for k,v in self.iteritems()] + self.__heap = [(v,k) for k,v in self.items()] self.__heap.sort() # builtin sort probably faster than O(n)-time heapify else: newPair = (val,key) diff --git a/python/altgraph/altgraph/GraphUtil.py b/python/altgraph/altgraph/GraphUtil.py index d3b6acd74d..f33440161b 100644 --- a/python/altgraph/altgraph/GraphUtil.py +++ b/python/altgraph/altgraph/GraphUtil.py @@ -24,7 +24,7 @@ def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=Fals if edge_num > max_edges: raise GraphError("inconsistent arguments to 'generate_random_graph'") - nodes = range(node_num) + nodes = list(range(node_num)) for node in nodes: g.add_node(node) @@ -49,7 +49,7 @@ def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=Fals return g def generate_scale_free_graph(steps, growth_num, self_loops=False, multi_edges=False): - ''' + r''' Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that will have *steps* \* *growth_num* nodes and a scale free (powerlaw) connectivity. Starting with a fully connected graph with *growth_num* nodes at every step *growth_num* nodes are added to the graph and are connected to existing nodes with @@ -107,7 +107,7 @@ def filter_stack(graph, head, filters): in *removes*. """ - visited, removes, orphans = set([head]), set(), set() + visited, removes, orphans = {head}, set(), set() stack = deque([(head, head)]) get_data = graph.node_data get_edges = graph.out_edges diff --git a/python/altgraph/altgraph/ObjectGraph.py b/python/altgraph/altgraph/ObjectGraph.py index d07f51b688..810a8362cb 100644 --- a/python/altgraph/altgraph/ObjectGraph.py +++ b/python/altgraph/altgraph/ObjectGraph.py @@ -6,11 +6,12 @@ A graph of objects that have a "graphident" attribute. graphident is the key for the object in the graph """ +from __future__ import print_function from altgraph import GraphError from altgraph.Graph import Graph from altgraph.GraphUtil import filter_stack -class ObjectGraph(object): +class ObjectGraph: """ A graph of objects that have a "graphident" attribute. graphident is the key for the object in the graph @@ -25,7 +26,7 @@ class ObjectGraph(object): graph.add_node(self, None) def __repr__(self): - return '<%s>' % (type(self).__name__,) + return '<{}>'.format(type(self).__name__) def flatten(self, condition=None, start=None): """ @@ -183,7 +184,7 @@ class ObjectGraph(object): Print a debug message with the given level """ if s and level <= self.debug: - print ("%s%s %s" % (" " * self.indent, s, ' '.join(map(repr, args)))) + print(("{}{} {}".format(" " * self.indent, s, ' '.join(map(repr, args))))) def msgin(self, level, s, *args): """ diff --git a/python/altgraph/altgraph_tests/test_dot.py b/python/altgraph/altgraph_tests/test_dot.py index 83993dad54..0903502507 100644 --- a/python/altgraph/altgraph_tests/test_dot.py +++ b/python/altgraph/altgraph_tests/test_dot.py @@ -32,7 +32,7 @@ class TestDot (unittest.TestCase): self.assertEqual(dot.neato, 'neato') self.assertEqual(dot.type, 'digraph') - self.assertEqual(dot.nodes, dict([(x, {}) for x in g])) + self.assertEqual(dot.nodes, {x: {} for x in g}) edges = {} for head in g: @@ -63,7 +63,7 @@ class TestDot (unittest.TestCase): self.assertEqual(dot.neato, '/usr/local/bin/neato') self.assertEqual(dot.type, 'graph') - self.assertEqual(dot.nodes, dict([(x, {'label': x}) for x in [1,2]])) + self.assertEqual(dot.nodes, {x: {'label': x} for x in [1,2]}) edges = {} for head in [1,2]: @@ -271,7 +271,7 @@ class TestDot (unittest.TestCase): try: dot.save_dot(fn) - fp = open(fn, 'r') + fp = open(fn) data = fp.read() fp.close() self.assertEqual(data, ''.join(dot)) diff --git a/python/altgraph/altgraph_tests/test_graphutil.py b/python/altgraph/altgraph_tests/test_graphutil.py index c1166237c1..ef618e5da2 100644 --- a/python/altgraph/altgraph_tests/test_graphutil.py +++ b/python/altgraph/altgraph_tests/test_graphutil.py @@ -107,11 +107,11 @@ class TestGraphUtil (unittest.TestCase): lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.2.3" ]) self.assertEqual(v, - set(["1", "1.1", "1.1.1", "1.1.2", "1.1.3", + {"1", "1.1", "1.1.1", "1.1.2", "1.1.3", "1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2", - "1.1.2.3"])) - self.assertEqual(r, set([ - "1.1.1", "1.1.2.3"])) + "1.1.2.3"}) + self.assertEqual(r, { + "1.1.1", "1.1.2.3"}) o.sort() self.assertEqual(o, @@ -124,11 +124,11 @@ class TestGraphUtil (unittest.TestCase): lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.1.2" ]) self.assertEqual(v, - set(["1", "1.1", "1.1.1", "1.1.2", "1.1.3", + {"1", "1.1", "1.1.1", "1.1.2", "1.1.3", "1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2", - "1.1.2.3"])) - self.assertEqual(r, set([ - "1.1.1", "1.1.1.2"])) + "1.1.2.3"}) + self.assertEqual(r, { + "1.1.1", "1.1.1.2"}) self.assertEqual(o, [ diff --git a/python/altgraph/altgraph_tests/test_object_graph.py b/python/altgraph/altgraph_tests/test_object_graph.py index 9035607e7a..004a623324 100644 --- a/python/altgraph/altgraph_tests/test_object_graph.py +++ b/python/altgraph/altgraph_tests/test_object_graph.py @@ -9,14 +9,14 @@ except ImportError: from io import StringIO -class Node (object): +class Node : def __init__(self, graphident): self.graphident = graphident class SubNode (Node): pass -class ArgNode (object): +class ArgNode : def __init__(self, graphident, *args, **kwds): self.graphident = graphident self.args = args diff --git a/python/altgraph/doc/conf.py b/python/altgraph/doc/conf.py index cd3fd9912e..3d5e2ace75 100644 --- a/python/altgraph/doc/conf.py +++ b/python/altgraph/doc/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # altgraph documentation build configuration file, created by # sphinx-quickstart on Tue Aug 31 11:04:49 2010. @@ -48,8 +47,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'altgraph' -copyright = u'2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert' +project = 'altgraph' +copyright = '2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -183,8 +182,8 @@ htmlhelp_basename = 'altgraphdoc' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'altgraph.tex', u'altgraph Documentation', - u'Ronald Oussoren', 'manual'), + ('index', 'altgraph.tex', 'altgraph Documentation', + 'Ronald Oussoren', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of diff --git a/python/altgraph/setup.py b/python/altgraph/setup.py index a1a4cb6eb2..15913a4417 100644 --- a/python/altgraph/setup.py +++ b/python/altgraph/setup.py @@ -15,6 +15,7 @@ Additional functionality: """ +from __future__ import print_function import sys import os import re @@ -28,7 +29,7 @@ import tarfile try: import urllib.request as urllib except ImportError: - import urllib + import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error from distutils import log try: from hashlib import md5 @@ -36,10 +37,7 @@ try: except ImportError: from md5 import md5 -if sys.version_info[0] == 2: - from ConfigParser import RawConfigParser, NoOptionError, NoSectionError -else: - from configparser import RawConfigParser, NoOptionError, NoSectionError +from configparser import RawConfigParser, NoOptionError, NoSectionError ROOTDIR = os.path.dirname(os.path.abspath(__file__)) @@ -226,7 +224,7 @@ def parse_setup_cfg(): else: parts = [] for nm in v.split(): - fp = open(nm, 'rU') + fp = open(nm) parts.append(fp.read()) fp.close() @@ -295,7 +293,7 @@ try: def get_pypi_src_download(package): url = 'https://pypi.python.org/pypi/%s/json'%(package,) - fp = urllib.urlopen(url) + fp = six.moves.urllib.request.urlopen(url) try: try: data = fp.read() @@ -323,7 +321,7 @@ except ImportError: def get_pypi_src_download(package): url = 'https://pypi.python.org/pypi/%s/json'%(package,) - fp = urllib.urlopen(url) + fp = six.moves.urllib.request.urlopen(url) try: try: data = fp.read() @@ -412,7 +410,7 @@ def _build_egg(egg, tarball, to_dir): # returning the result log.warn(egg) if not os.path.exists(egg): - raise IOError('Could not build the egg.') + raise OSError('Could not build the egg.') def _do_download(to_dir, packagename=SETUPTOOLS_PACKAGE): @@ -437,7 +435,7 @@ def download_setuptools(packagename, to_dir): try: from urllib.request import urlopen except ImportError: - from urllib2 import urlopen + from urllib.request import urlopen chksum, url = get_pypi_src_download(packagename) tgz_name = os.path.basename(url) @@ -579,11 +577,11 @@ else: import shutil import zipfile import os - import urllib + import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import StringIO from base64 import standard_b64encode - import httplib - import urlparse + import six.moves.http_client + import six.moves.urllib.parse # Extract the package name from distutils metadata meta = self.distribution.metadata @@ -611,7 +609,7 @@ else: fullname = os.path.join(toplevel, fn) relname = os.path.relpath(fullname, 'doc/_build/html') - print ("%s -> %s"%(fullname, relname)) + print(("%s -> %s"%(fullname, relname))) zf.write(fullname, relname) @@ -658,13 +656,13 @@ else: self.announce("Uploading documentation to %s"%(self.repository,), log.INFO) schema, netloc, url, params, query, fragments = \ - urlparse.urlparse(self.repository) + six.moves.urllib.parse.urlparse(self.repository) if schema == 'http': - http = httplib.HTTPConnection(netloc) + http = six.moves.http_client.HTTPConnection(netloc) elif schema == 'https': - http = httplib.HTTPSConnection(netloc) + http = six.moves.http_client.HTTPSConnection(netloc) else: raise AssertionError("unsupported schema "+schema) @@ -679,22 +677,22 @@ else: http.putheader('Authorization', auth) http.endheaders() http.send(body) - except socket.error: + except OSError: e = socket.exc_info()[1] self.announce(str(e), log.ERROR) return r = http.getresponse() if r.status in (200, 301): - self.announce('Upload succeeded (%s): %s' % (r.status, r.reason), + self.announce('Upload succeeded ({}): {}'.format(r.status, r.reason), log.INFO) else: - self.announce('Upload failed (%s): %s' % (r.status, r.reason), + self.announce('Upload failed ({}): {}'.format(r.status, r.reason), log.ERROR) - print ('-'*75) - print (r.read()) - print ('-'*75) + print(('-'*75)) + print((r.read())) + print(('-'*75)) def recursiveGlob(root, pathPattern): @@ -718,7 +716,7 @@ def importExternalTestCases(unittest, """ testFiles = recursiveGlob(root, pathPattern) - testModules = map(lambda x:x[len(root)+1:-3].replace('/', '.'), testFiles) + testModules = [x[len(root)+1:-3].replace('/', '.') for x in testFiles] if package is not None: testModules = [(package + '.' + m) for m in testModules] @@ -728,7 +726,7 @@ def importExternalTestCases(unittest, try: module = __import__(modName) except ImportError: - print("SKIP %s: %s"%(modName, sys.exc_info()[1])) + print(("SKIP %s: %s"%(modName, sys.exc_info()[1]))) continue if '.' in modName: @@ -843,7 +841,7 @@ class test (Command): xpass=len(getattr(result, 'expectedSuccesses', [])), skip=len(getattr(result, 'skipped', [])), ) - print("SUMMARY: %s"%(summary,)) + print(("SUMMARY: %s"%(summary,))) finally: self.remove_from_sys_path() diff --git a/python/bitstring/bitstring.py b/python/bitstring/bitstring.py index 86f969c7f2..b7af104ee5 100644 --- a/python/bitstring/bitstring.py +++ b/python/bitstring/bitstring.py @@ -13,12 +13,12 @@ BitStream -- A mutable container with streaming methods. Bits (base class) / \ - + mutating methods / \ + streaming methods + + mutating methods / \\ + streaming methods / \ BitArray ConstBitStream - \ / - \ / - \ / + \\ / + \\ / + \\ / BitStream Functions: @@ -127,7 +127,7 @@ class CreationError(Error, ValueError): Error.__init__(self, *params) -class ConstByteStore(object): +class ConstByteStore: """Stores raw bytes together with a bit offset and length. Used internally - not part of public interface. @@ -391,7 +391,7 @@ def equal(a, b): return a_val == b_val -class MmapByteArray(object): +class MmapByteArray: """Looks like a bytearray, but from an mmap. Not part of public interface. @@ -446,13 +446,13 @@ BYTE_REVERSAL_DICT = dict() try: xrange for i in range(256): - BYTE_REVERSAL_DICT[i] = chr(int("{0:08b}".format(i)[::-1], 2)) + BYTE_REVERSAL_DICT[i] = chr(int("{:08b}".format(i)[::-1], 2)) except NameError: for i in range(256): - BYTE_REVERSAL_DICT[i] = bytes([int("{0:08b}".format(i)[::-1], 2)]) + BYTE_REVERSAL_DICT[i] = bytes([int("{:08b}".format(i)[::-1], 2)]) from io import IOBase as file xrange = range - basestring = str + str = str # Python 2.x octals start with '0', in Python 3 it's '0o' LEADING_OCT_CHARS = len(oct(1)) - 1 @@ -588,7 +588,7 @@ def tokenparser(fmt, keys=None, token_cache={}): # and if you don't specify a 'name' then the default is 'uint': m2 = DEFAULT_UINT.match(token) if not m2: - raise ValueError("Don't understand token '{0}'.".format(token)) + raise ValueError("Don't understand token '{}'.".format(token)) if m1: name = m1.group('name') length = m1.group('len') @@ -619,7 +619,7 @@ def tokenparser(fmt, keys=None, token_cache={}): raise ValueError("Can't read a token with a negative length.") except ValueError: if not keys or length not in keys: - raise ValueError("Don't understand length '{0}' of token.".format(length)) + raise ValueError("Don't understand length '{}' of token.".format(length)) ret_vals.append([name, length, value]) # This multiplies by the multiplicative factor, but this means that # we can't allow keyword values as multipliers (e.g. n*uint:8). @@ -653,7 +653,7 @@ def expand_brackets(s): break p += 1 if count: - raise ValueError("Unbalanced parenthesis in '{0}'.".format(s)) + raise ValueError("Unbalanced parenthesis in '{}'.".format(s)) if start == 0 or s[start - 1] != '*': s = s[0:start] + s[start + 1:p] + s[p + 1:] else: @@ -663,18 +663,18 @@ def expand_brackets(s): matchstart = m.start('factor') s = s[0:matchstart] + (factor - 1) * (s[start + 1:p] + ',') + s[start + 1:p] + s[p + 1:] else: - raise ValueError("Failed to parse '{0}'.".format(s)) + raise ValueError("Failed to parse '{}'.".format(s)) return s # This converts a single octal digit to 3 bits. -OCT_TO_BITS = ['{0:03b}'.format(i) for i in xrange(8)] +OCT_TO_BITS = ['{:03b}'.format(i) for i in range(8)] # A dictionary of number of 1 bits contained in binary representation of any byte -BIT_COUNT = dict(zip(xrange(256), [bin(i).count('1') for i in xrange(256)])) +BIT_COUNT = dict(zip(range(256), [bin(i).count('1') for i in range(256)])) -class Bits(object): +class Bits: """A container holding an immutable sequence of bits. For a mutable container use the BitArray class instead. @@ -772,7 +772,7 @@ class Bits(object): # For instances auto-initialised with a string we intern the # instance for re-use. try: - if isinstance(auto, basestring): + if isinstance(auto, str): try: return _cache[auto] except KeyError: @@ -792,7 +792,7 @@ class Bits(object): return auto except TypeError: pass - x = super(Bits, cls).__new__(cls) + x = super().__new__(cls) x._initialise(auto, length, offset, **kwargs) return x @@ -843,16 +843,16 @@ class Bits(object): return self def __lt__(self, other): - raise TypeError("unorderable type: {0}".format(type(self).__name__)) + raise TypeError("unorderable type: {}".format(type(self).__name__)) def __gt__(self, other): - raise TypeError("unorderable type: {0}".format(type(self).__name__)) + raise TypeError("unorderable type: {}".format(type(self).__name__)) def __le__(self, other): - raise TypeError("unorderable type: {0}".format(type(self).__name__)) + raise TypeError("unorderable type: {}".format(type(self).__name__)) def __ge__(self, other): - raise TypeError("unorderable type: {0}".format(type(self).__name__)) + raise TypeError("unorderable type: {}".format(type(self).__name__)) def __add__(self, bs): """Concatenate bitstrings and return new bitstring. @@ -967,14 +967,14 @@ class Bits(object): if self._datastore.byteoffset or self._offset: offsetstring = ", offset=%d" % (self._datastore._rawarray.byteoffset * 8 + self._offset) lengthstring = ", length=%d" % length - return "{0}(filename='{1}'{2}{3})".format(self.__class__.__name__, + return "{}(filename='{}'{}{})".format(self.__class__.__name__, self._datastore._rawarray.source.name, lengthstring, offsetstring) else: s = self.__str__() lengthstring = '' if s.endswith('...'): - lengthstring = " # length={0}".format(length) - return "{0}('{1}'){2}".format(self.__class__.__name__, s, lengthstring) + lengthstring = " # length={}".format(length) + return "{}('{}'){}".format(self.__class__.__name__, s, lengthstring) def __eq__(self, bs): """Return True if two bitstrings have the same binary representation. @@ -1195,7 +1195,7 @@ class Bits(object): def _assertsanity(self): """Check internal self consistency as a debugging aid.""" assert self.len >= 0 - assert 0 <= self._offset, "offset={0}".format(self._offset) + assert 0 <= self._offset, "offset={}".format(self._offset) assert (self.len + self._offset + 7) // 8 == self._datastore.bytelength + self._datastore.byteoffset return True @@ -1211,9 +1211,9 @@ class Bits(object): if value is None: if token_length is None: - error = "Token has no value ({0}=???).".format(name) + error = "Token has no value ({}=???).".format(name) else: - error = "Token has no value ({0}:{1}=???).".format(name, token_length) + error = "Token has no value ({}:{}=???).".format(name, token_length) raise ValueError(error) try: b = cls(**{_tokenname_to_initialiser[name]: value}) @@ -1270,7 +1270,7 @@ class Bits(object): raise CreationError("The length keyword isn't applicable to this initialiser.") if offset: raise CreationError("The offset keyword isn't applicable to this initialiser.") - if isinstance(s, basestring): + if isinstance(s, str): bs = self._converttobitstring(s) assert bs._offset == 0 self._setbytes_unsafe(bs._datastore.rawbytes, bs.length, 0) @@ -1286,11 +1286,11 @@ class Bits(object): data = bytearray((s + 7) // 8) self._datastore = ByteStore(data, s, 0) return - if isinstance(s, collections.Iterable): + if isinstance(s, collections.abc.Iterable): # Evaluate each item as True or False and set bits to 1 or 0. self._setbin_unsafe(''.join(str(int(bool(x))) for x in s)) return - raise TypeError("Cannot initialise bitstring from {0}.".format(type(s))) + raise TypeError("Cannot initialise bitstring from {}.".format(type(s))) def _setfile(self, filename, length, offset): """Use file as source of bits.""" @@ -1499,7 +1499,7 @@ class Bits(object): val <<= 8 * chunksize val += struct.unpack(' self.length - pos: raise ReadError("Reading off the end of the data. " - "Tried to read {0} bits when only {1} available.".format(int(length), self.length - pos)) + "Tried to read {} bits when only {} available.".format(int(length), self.length - pos)) try: val = name_to_read[name](self, length, pos) return val, pos + length except KeyError: if name == 'pad': return None, pos + length - raise ValueError("Can't parse token {0}:{1}".format(name, length)) + raise ValueError("Can't parse token {}:{}".format(name, length)) except TypeError: # This is for the 'ue', 'se' and 'bool' tokens. They will also return the new pos. return name_to_read[name](self, pos) @@ -2169,7 +2169,7 @@ class Bits(object): """Invert every bit.""" set = self._datastore.setbyte get = self._datastore.getbyte - for p in xrange(self._datastore.byteoffset, self._datastore.byteoffset + self._datastore.bytelength): + for p in range(self._datastore.byteoffset, self._datastore.byteoffset + self._datastore.bytelength): set(p, 256 + ~get(p)) def _ilshift(self, n): @@ -2212,7 +2212,7 @@ class Bits(object): self._datastore = offsetcopy(self._datastore, bs_bitoffset) a = self._datastore.rawbytes b = bs._datastore.rawbytes - for i in xrange(len(a)): + for i in range(len(a)): a[i] = f(a[i + self_byteoffset], b[i + bs_byteoffset]) return self @@ -2267,13 +2267,13 @@ class Bits(object): def _readlist(self, fmt, pos, **kwargs): tokens = [] stretchy_token = None - if isinstance(fmt, basestring): + if isinstance(fmt, str): fmt = [fmt] # Not very optimal this, but replace integers with 'bits' tokens # TODO: optimise for i, f in enumerate(fmt): if isinstance(f, numbers.Integral): - fmt[i] = "bits:{0}".format(f) + fmt[i] = "bits:{}".format(f) for f_item in fmt: stretchy, tkns = tokenparser(f_item, tuple(sorted(kwargs.keys()))) if stretchy: @@ -2720,12 +2720,12 @@ class Bits(object): value = bool(value) length = self.len if pos is None: - pos = xrange(self.len) + pos = range(self.len) for p in pos: if p < 0: p += length if not 0 <= p < length: - raise IndexError("Bit position {0} out of range.".format(p)) + raise IndexError("Bit position {} out of range.".format(p)) if not self._datastore.getbit(p) is value: return False return True @@ -2742,12 +2742,12 @@ class Bits(object): value = bool(value) length = self.len if pos is None: - pos = xrange(self.len) + pos = range(self.len) for p in pos: if p < 0: p += length if not 0 <= p < length: - raise IndexError("Bit position {0} out of range.".format(p)) + raise IndexError("Bit position {} out of range.".format(p)) if self._datastore.getbit(p) is value: return True return False @@ -2766,7 +2766,7 @@ class Bits(object): return 0 # count the number of 1s (from which it's easy to work out the 0s). # Don't count the final byte yet. - count = sum(BIT_COUNT[self._datastore.getbyte(i)] for i in xrange(self._datastore.bytelength - 1)) + count = sum(BIT_COUNT[self._datastore.getbyte(i)] for i in range(self._datastore.bytelength - 1)) # adjust for bits at start that aren't part of the bitstring if self._offset: count -= BIT_COUNT[self._datastore.getbyte(0) >> (8 - self._offset)] @@ -3043,7 +3043,7 @@ class BitArray(Bits): self._ensureinmemory() def __new__(cls, auto=None, length=None, offset=None, **kwargs): - x = super(BitArray, cls).__new__(cls) + x = super().__new__(cls) y = Bits.__new__(BitArray, auto, length, offset, **kwargs) x._datastore = y._datastore return x @@ -3104,7 +3104,7 @@ class BitArray(Bits): if value in (1, -1): self._set(key) return - raise ValueError("Cannot set a single bit with integer {0}.".format(value)) + raise ValueError("Cannot set a single bit with integer {}.".format(value)) value = Bits(value) if value.len == 1: # TODO: this can't be optimal @@ -3134,7 +3134,7 @@ class BitArray(Bits): value = Bits(value) except TypeError: raise TypeError("Bitstring, integer or string expected. " - "Got {0}.".format(type(value))) + "Got {}.".format(type(value))) if key.start is not None: start = key.start if key.start < 0: @@ -3458,21 +3458,21 @@ class BitArray(Bits): """ f = self._set if value else self._unset if pos is None: - pos = xrange(self.len) + pos = range(self.len) try: length = self.len for p in pos: if p < 0: p += length if not 0 <= p < length: - raise IndexError("Bit position {0} out of range.".format(p)) + raise IndexError("Bit position {} out of range.".format(p)) f(p) except TypeError: # Single pos if pos < 0: pos += self.len if not 0 <= pos < length: - raise IndexError("Bit position {0} out of range.".format(pos)) + raise IndexError("Bit position {} out of range.".format(pos)) f(pos) def invert(self, pos=None): @@ -3487,7 +3487,7 @@ class BitArray(Bits): if pos is None: self._invert_all() return - if not isinstance(pos, collections.Iterable): + if not isinstance(pos, collections.abc.Iterable): pos = (pos,) length = self.len @@ -3495,7 +3495,7 @@ class BitArray(Bits): if p < 0: p += length if not 0 <= p < length: - raise IndexError("Bit position {0} out of range.".format(p)) + raise IndexError("Bit position {} out of range.".format(p)) self._invert(p) def ror(self, bits, start=None, end=None): @@ -3560,12 +3560,12 @@ class BitArray(Bits): bytesizes = [(end - start) // 8] elif isinstance(fmt, numbers.Integral): if fmt < 0: - raise ValueError("Improper byte length {0}.".format(fmt)) + raise ValueError("Improper byte length {}.".format(fmt)) bytesizes = [fmt] - elif isinstance(fmt, basestring): + elif isinstance(fmt, str): m = STRUCT_PACK_RE.match(fmt) if not m: - raise ValueError("Cannot parse format string {0}.".format(fmt)) + raise ValueError("Cannot parse format string {}.".format(fmt)) # Split the format string into a list of 'q', '4h' etc. formatlist = re.findall(STRUCT_SPLIT_RE, m.group('fmt')) # Now deal with multiplicative factors, 4h -> hhhh etc. @@ -3575,11 +3575,11 @@ class BitArray(Bits): bytesizes.append(PACK_CODE_SIZE[f]) else: bytesizes.extend([PACK_CODE_SIZE[f[-1]]] * int(f[:-1])) - elif isinstance(fmt, collections.Iterable): + elif isinstance(fmt, collections.abc.Iterable): bytesizes = fmt for bytesize in bytesizes: if not isinstance(bytesize, numbers.Integral) or bytesize < 0: - raise ValueError("Improper byte length {0}.".format(bytesize)) + raise ValueError("Improper byte length {}.".format(bytesize)) else: raise TypeError("Format must be an integer, string or iterable.") @@ -3593,7 +3593,7 @@ class BitArray(Bits): else: # Just try one (set of) byteswap(s). finalbit = start + totalbitsize - for patternend in xrange(start + totalbitsize, finalbit + 1, totalbitsize): + for patternend in range(start + totalbitsize, finalbit + 1, totalbitsize): bytestart = patternend - totalbitsize for bytesize in bytesizes: byteend = bytestart + bytesize * 8 @@ -3781,7 +3781,7 @@ class ConstBitStream(Bits): self._pos = 0 def __new__(cls, auto=None, length=None, offset=None, **kwargs): - x = super(ConstBitStream, cls).__new__(cls) + x = super().__new__(cls) x._initialise(auto, length, offset, **kwargs) return x @@ -3880,7 +3880,7 @@ class ConstBitStream(Bits): _, token = tokenparser(fmt) if len(token) != 1: self._pos = p - raise ValueError("Format string should be a single token, not {0} " + raise ValueError("Format string should be a single token, not {} " "tokens - use readlist() instead.".format(len(token))) name, length, _ = token[0] if length is None: @@ -4121,7 +4121,7 @@ class BitStream(ConstBitStream, BitArray): self._ensureinmemory() def __new__(cls, auto=None, length=None, offset=None, **kwargs): - x = super(BitStream, cls).__new__(cls) + x = super().__new__(cls) x._initialise(auto, length, offset, **kwargs) return x @@ -4186,7 +4186,7 @@ def pack(fmt, *values, **kwargs): """ tokens = [] - if isinstance(fmt, basestring): + if isinstance(fmt, str): fmt = [fmt] try: for f_item in fmt: diff --git a/python/bitstring/test/test_bitarray.py b/python/bitstring/test/test_bitarray.py index b80f90617b..9436f84620 100644 --- a/python/bitstring/test/test_bitarray.py +++ b/python/bitstring/test/test_bitarray.py @@ -255,7 +255,7 @@ class SliceAssignment(unittest.TestCase): self.assertTrue(False) except ValueError: pass - class A(object): pass + class A: pass try: a[1:2] = A() self.assertTrue(False) diff --git a/python/bitstring/test/test_bitstream.py b/python/bitstring/test/test_bitstream.py index f94193d324..4ddd5b1779 100644 --- a/python/bitstring/test/test_bitstream.py +++ b/python/bitstring/test/test_bitstream.py @@ -757,7 +757,7 @@ class FromFile(unittest.TestCase): # and so this test won't work for anyone except me! try: s = ConstBitStream(filename='11GB.mkv') - except IOError: + except OSError: return self.assertEqual(s.len, 11743020505 * 8) self.assertEqual(s[1000000000:1000000100].hex, 'bdef7335d4545f680d669ce24') @@ -1529,7 +1529,7 @@ class Adding(unittest.TestCase): s5 = BitStream(bytes=b'\xff', offset=2, length=3) s6 = BitStream('0b111') self.assertTrue(s5 == s6) - class A(object): + class A: pass self.assertFalse(s5 == A()) @@ -2493,7 +2493,7 @@ class Split(unittest.TestCase): s = pack('<2h', 1, 2) a, b = s.unpack('<2h') self.assertEqual((a, b), (1, 2)) - s = pack('<100q', *range(100)) + s = pack('<100q', *list(range(100))) self.assertEqual(s.len, 100 * 64) self.assertEqual(s[44*64:45*64].uintle, 44) s = pack('@L0B2h', 5, 5, 5) @@ -2812,7 +2812,7 @@ class Split(unittest.TestCase): b = ConstBitStream('0x2') c = ConstBitStream('0x1') c.pos = 3 - s = set((a, b, c)) + s = {a, b, c} self.assertEqual(len(s), 2) self.assertEqual(hash(a), hash(c)) @@ -2875,9 +2875,9 @@ class Set(unittest.TestCase): def testSetList(self): a = BitStream(length=18) - a.set(True, range(18)) + a.set(True, list(range(18))) self.assertEqual(a.int, -1) - a.set(False, range(18)) + a.set(False, list(range(18))) self.assertEqual(a.int, 0) def testUnset(self): @@ -2907,7 +2907,7 @@ class Set(unittest.TestCase): class Invert(unittest.TestCase): def testInvertBits(self): a = BitStream('0b111000') - a.invert(range(a.len)) + a.invert(list(range(a.len))) self.assertEqual(a, '0b000111') a.invert([0, 1, -1]) self.assertEqual(a, '0b110110') @@ -3456,8 +3456,8 @@ class Bugs(unittest.TestCase): self.assertEqual(s.len, 17) def testInitFromIterable(self): - self.assertTrue(isinstance(range(10), collections.Iterable)) - s = ConstBitStream(range(12)) + self.assertTrue(isinstance(list(range(10)), collections.abc.Iterable)) + s = ConstBitStream(list(range(12))) self.assertEqual(s, '0x7ff') def testFunctionNegativeIndices(self): @@ -3554,7 +3554,7 @@ class Bugs(unittest.TestCase): self.assertRaises(ValueError, a.rol, 5, start=-4, end=-6) def testByteSwapInt(self): - s = pack('5*uintle:16', *range(10, 15)) + s = pack('5*uintle:16', *list(range(10, 15))) self.assertEqual(list(range(10, 15)), s.unpack('5*uintle:16')) swaps = s.byteswap(2) self.assertEqual(list(range(10, 15)), s.unpack('5*uintbe:16')) @@ -3588,7 +3588,7 @@ class Bugs(unittest.TestCase): def testByteSwapIterable(self): s = BitStream('0x0011223344556677') - swaps = s.byteswap(range(1, 4), repeat=False) + swaps = s.byteswap(list(range(1, 4)), repeat=False) self.assertEqual(swaps, 1) self.assertEqual(s, '0x0022115544336677') swaps = s.byteswap([2], start=8) @@ -3628,7 +3628,7 @@ class Bugs(unittest.TestCase): def testBracketTokens(self): s = BitStream('3*(0x0, 0b1)') self.assertEqual(s, '0x0, 0b1, 0x0, 0b1, 0x0, 0b1') - s = pack('2*(uint:12, 3*(7, 6))', *range(3, 17)) + s = pack('2*(uint:12, 3*(7, 6))', *list(range(3, 17))) a = s.unpack('12, 7, 6, 7, 6, 7, 6, 12, 7, 6, 7, 6, 7, 6') self.assertEqual(a, list(range(3, 17))) b = s.unpack('2*(12,3*(7,6))') diff --git a/python/blessings/blessings/__init__.py b/python/blessings/blessings/__init__.py index 081288ba68..e5e71e3654 100644 --- a/python/blessings/blessings/__init__.py +++ b/python/blessings/blessings/__init__.py @@ -25,7 +25,7 @@ if ('3', '0', '0') <= python_version_tuple() < ('3', '2', '2+'): # Good till 3. __all__ = ['Terminal'] -class Terminal(object): +class Terminal: """An abstraction around terminal capabilities Unlike curses, this doesn't require clearing the screen before doing @@ -189,7 +189,7 @@ class Terminal(object): for descriptor in self._init_descriptor, sys.__stdout__: try: return struct.unpack('hhhh', ioctl(descriptor, TIOCGWINSZ, '\000' * 8))[0:2] - except IOError: + except OSError: pass return None, None # Should never get here @@ -201,9 +201,9 @@ class Terminal(object): term = Terminal() with term.location(2, 5): - print 'Hello, world!' + print('Hello, world!') for x in xrange(10): - print 'I can do it %i times!' % x + print('I can do it %i times!' % x) Specify ``x`` to move to a certain column, ``y`` to move to a certain row, or both. @@ -272,7 +272,7 @@ class Terminal(object): # optimization: combine all formatting into a single escape # sequence. return self._formatting_string( - u''.join(self._resolve_formatter(s) for s in formatters)) + ''.join(self._resolve_formatter(s) for s in formatters)) else: return ParametrizingString(self._resolve_capability(attr)) @@ -289,7 +289,7 @@ class Terminal(object): # contain chars > 127, and UTF-8 never changes anything within that # range.. return code.decode('utf-8') - return u'' + return '' def _resolve_color(self, color): """Resolve a color like red or on_bright_green into a callable capability.""" @@ -326,14 +326,14 @@ def derivative_colors(colors): [('on_bright_' + c) for c in colors]) -COLORS = set(['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']) +COLORS = {'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'} COLORS.update(derivative_colors(COLORS)) COMPOUNDABLES = (COLORS | - set(['bold', 'underline', 'reverse', 'blink', 'dim', 'italic', - 'shadow', 'standout', 'subscript', 'superscript'])) + {'bold', 'underline', 'reverse', 'blink', 'dim', 'italic', + 'shadow', 'standout', 'subscript', 'superscript'}) -class ParametrizingString(unicode): +class ParametrizingString(str): """A Unicode string which can be called to parametrize it as a terminal capability""" def __new__(cls, formatting, normal=None): """Instantiate. @@ -343,7 +343,7 @@ class ParametrizingString(unicode): "normal" capability. """ - new = unicode.__new__(cls, formatting) + new = str.__new__(cls, formatting) new._normal = normal return new @@ -360,11 +360,11 @@ class ParametrizingString(unicode): # running simply `nosetests` (without progressive) on nose- # progressive. Perhaps the terminal has gone away between calling # tigetstr and calling tparm. - return u'' + return '' except TypeError: # If the first non-int (i.e. incorrect) arg was a string, suggest # something intelligent: - if len(args) == 1 and isinstance(args[0], basestring): + if len(args) == 1 and isinstance(args[0], str): raise TypeError( 'A native or nonexistent capability template received ' '%r when it was expecting ints. You probably misspelled a ' @@ -375,10 +375,10 @@ class ParametrizingString(unicode): raise -class FormattingString(unicode): +class FormattingString(str): """A Unicode string which can be called upon a piece of text to wrap it in formatting""" def __new__(cls, formatting, normal): - new = unicode.__new__(cls, formatting) + new = str.__new__(cls, formatting) new._normal = normal return new @@ -393,7 +393,7 @@ class FormattingString(unicode): return self + text + self._normal -class NullCallableString(unicode): +class NullCallableString(str): """A dummy class to stand in for ``FormattingString`` and ``ParametrizingString`` A callable bytestring that returns an empty Unicode when called with an int @@ -402,12 +402,12 @@ class NullCallableString(unicode): """ def __new__(cls): - new = unicode.__new__(cls, u'') + new = str.__new__(cls, '') return new def __call__(self, arg): if isinstance(arg, int): - return u'' + return '' return arg # TODO: Force even strs in Python 2.x to be unicodes? Nah. How would I know what encoding to use to convert it? @@ -429,7 +429,7 @@ def split_into_formatters(compound): return merged_segs -class Location(object): +class Location: """Context manager for temporarily moving the cursor""" def __init__(self, term, x=None, y=None): self.x, self.y = x, y diff --git a/python/blessings/blessings/tests.py b/python/blessings/blessings/tests.py index a02a3924a8..09b05559f8 100644 --- a/python/blessings/blessings/tests.py +++ b/python/blessings/blessings/tests.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Automated tests (as opposed to human-verified test patterns) It was tempting to mock out curses to get predictable output from ``tigetstr``, @@ -52,8 +51,8 @@ def test_capability(): def test_capability_without_tty(): """Assert capability templates are '' when stream is not a tty.""" t = TestTerminal(stream=StringIO()) - eq_(t.save, u'') - eq_(t.red, u'') + eq_(t.save, '') + eq_(t.red, '') def test_capability_with_forced_tty(): @@ -84,11 +83,11 @@ def test_location(): t = TestTerminal(stream=StringIO(), force_styling=True) with t.location(3, 4): - t.stream.write(u'hi') + t.stream.write('hi') eq_(t.stream.getvalue(), unicode_cap('sc') + unicode_parm('cup', 4, 3) + - u'hi' + + 'hi' + unicode_cap('rc')) @@ -111,7 +110,7 @@ def test_null_fileno(): out = StringIO() out.fileno = None t = TestTerminal(stream=out) - eq_(t.save, u'') + eq_(t.save, '') def test_mnemonic_colors(): @@ -179,26 +178,26 @@ def test_formatting_functions(): """Test crazy-ass formatting wrappers, both simple and compound.""" t = TestTerminal() # By now, it should be safe to use sugared attributes. Other tests test those. - eq_(t.bold(u'hi'), t.bold + u'hi' + t.normal) - eq_(t.green('hi'), t.green + u'hi' + t.normal) # Plain strs for Python 2.x + eq_(t.bold('hi'), t.bold + 'hi' + t.normal) + eq_(t.green('hi'), t.green + 'hi' + t.normal) # Plain strs for Python 2.x # Test some non-ASCII chars, probably not necessary: - eq_(t.bold_green(u'boö'), t.bold + t.green + u'boö' + t.normal) + eq_(t.bold_green('boö'), t.bold + t.green + 'boö' + t.normal) eq_(t.bold_underline_green_on_red('boo'), - t.bold + t.underline + t.green + t.on_red + u'boo' + t.normal) + t.bold + t.underline + t.green + t.on_red + 'boo' + t.normal) # Don't spell things like this: eq_(t.on_bright_red_bold_bright_green_underline('meh'), - t.on_bright_red + t.bold + t.bright_green + t.underline + u'meh' + t.normal) + t.on_bright_red + t.bold + t.bright_green + t.underline + 'meh' + t.normal) def test_formatting_functions_without_tty(): """Test crazy-ass formatting wrappers when there's no tty.""" t = TestTerminal(stream=StringIO()) - eq_(t.bold(u'hi'), u'hi') - eq_(t.green('hi'), u'hi') + eq_(t.bold('hi'), 'hi') + eq_(t.green('hi'), 'hi') # Test non-ASCII chars, no longer really necessary: - eq_(t.bold_green(u'boö'), u'boö') - eq_(t.bold_underline_green_on_red('loo'), u'loo') - eq_(t.on_bright_red_bold_bright_green_underline('meh'), u'meh') + eq_(t.bold_green('boö'), 'boö') + eq_(t.bold_underline_green_on_red('loo'), 'loo') + eq_(t.on_bright_red_bold_bright_green_underline('meh'), 'meh') def test_nice_formatting_errors(): @@ -206,22 +205,22 @@ def test_nice_formatting_errors(): t = TestTerminal() try: t.bold_misspelled('hey') - except TypeError, e: + except TypeError as e: assert 'probably misspelled' in e.args[0] try: - t.bold_misspelled(u'hey') # unicode - except TypeError, e: + t.bold_misspelled('hey') # unicode + except TypeError as e: assert 'probably misspelled' in e.args[0] try: t.bold_misspelled(None) # an arbitrary non-string - except TypeError, e: + except TypeError as e: assert 'probably misspelled' not in e.args[0] try: t.bold_misspelled('a', 'b') # >1 string arg - except TypeError, e: + except TypeError as e: assert 'probably misspelled' not in e.args[0] diff --git a/python/blessings/setup.py b/python/blessings/setup.py index 6af55452d8..57f3d4cf8d 100644 --- a/python/blessings/setup.py +++ b/python/blessings/setup.py @@ -4,8 +4,7 @@ from setuptools import setup, find_packages extra_setup = {} -if sys.version_info >= (3,): - extra_setup['use_2to3'] = True +extra_setup['use_2to3'] = True setup( name='blessings', diff --git a/python/compare-locales/compare_locales/checks.py b/python/compare-locales/compare_locales/checks.py index 0faffcc698..654d335ebd 100644 --- a/python/compare-locales/compare_locales/checks.py +++ b/python/compare-locales/compare_locales/checks.py @@ -44,7 +44,7 @@ class PrintfException(Exception): class PropertiesChecker(Checker): '''Tests to run on .properties files. ''' - pattern = re.compile('.*\.properties$') + pattern = re.compile(r'.*\.properties$') printf = re.compile(r'%(?P%|' r'(?:(?P[1-9][0-9]*)\$)?' r'(?P\*|[0-9]+)?' @@ -95,7 +95,7 @@ class PropertiesChecker(Checker): def checkPrintf(self, refSpecs, l10nValue): try: l10nSpecs = self.getPrintfSpecs(l10nValue) - except PrintfException, e: + except PrintfException as e: yield ('error', e.pos, e.msg, 'printf') return if refSpecs != l10nSpecs: @@ -112,20 +112,20 @@ class PropertiesChecker(Checker): # trailing specs missing, that's just a warning warn = ', '.join('trailing argument %d `%s` missing' % (i+1, refSpecs[i]) - for i in xrange(i1, i2)) + for i in range(i1, i2)) else: - for i in xrange(i1, i2): + for i in range(i1, i2): msgs.append('argument %d `%s` missing' % (i+1, refSpecs[i])) continue if action == 'insert': # obsolete argument in l10n - for i in xrange(j1, j2): + for i in range(j1, j2): msgs.append('argument %d `%s` obsolete' % (i+1, l10nSpecs[i])) continue if action == 'replace': - for i, j in zip(xrange(i1, i2), xrange(j1, j2)): + for i, j in zip(range(i1, i2), range(j1, j2)): msgs.append('argument %d `%s` should be `%s`' % (j+1, l10nSpecs[j], refSpecs[i])) if msgs: @@ -183,7 +183,7 @@ class DTDChecker(Checker): Also checks for some CSS and number heuristics in the values. """ - pattern = re.compile('.*\.dtd$') + pattern = re.compile(r'.*\.dtd$') eref = re.compile('&(%s);' % DTDParser.Name) tmpl = ''' @@ -253,7 +253,7 @@ class DTDChecker(Checker): parser.parse(StringIO(self.tmpl % (refEnt.all.encode('utf-8') + entities, '&%s;' % refEnt.key.encode('utf-8')))) - except sax.SAXParseException, e: + except sax.SAXParseException as e: yield ('warning', (0, 0), "can't parse en-US value", 'xmlparse') @@ -275,7 +275,7 @@ class DTDChecker(Checker): parser.parse(StringIO(self.tmpl % ( l10nEnt.all.encode('utf-8') + _entities, '&%s;' % l10nEnt.key.encode('utf-8')))) - except sax.SAXParseException, e: + except sax.SAXParseException as e: # xml parse error, yield error # sometimes, the error is reported on our fake closing # element, make that the end of the last line @@ -293,7 +293,7 @@ class DTDChecker(Checker): col -= len("= lines[i - 1]: return (i, offset - lines[i - 1]) return (1, offset) - l10n_list = l10n_map.keys() + l10n_list = list(l10n_map.keys()) l10n_list.sort() ar = AddRemove() ar.set_left(ref_list) @@ -542,7 +543,7 @@ class ContentComparer: if tp == 'error' and self.merge_stage is not None: skips.append(l10nent) self.notify(tp, l10n, - u"%s at line %d, column %d for %s" % + "%s at line %d, column %d for %s" % (msg, _l, col, refent.key)) pass if missing: @@ -573,7 +574,7 @@ class ContentComparer: try: p.readContents(f.getContents()) entities, map = p.parse() - except Exception, e: + except Exception as e: self.notify('error', f, str(e)) return self.notify('missingInFiles', missing, len(map)) @@ -615,7 +616,7 @@ def compareApp(app, other_observer=None, merge_stage=None, clobber=False): clobberdir = os.path.join(locale_merge, module) if os.path.exists(clobberdir): shutil.rmtree(clobberdir) - print "clobbered " + clobberdir + print(("clobbered " + clobberdir)) dir_comp.compareWith(localization) return comparer.observer diff --git a/python/compare-locales/compare_locales/parser.py b/python/compare-locales/compare_locales/parser.py index a97cf201be..cfbc5a925d 100644 --- a/python/compare-locales/compare_locales/parser.py +++ b/python/compare-locales/compare_locales/parser.py @@ -122,10 +122,10 @@ class Parser: f = codecs.open(file, 'r', self.encoding) try: self.contents = f.read() - except UnicodeDecodeError, e: + except UnicodeDecodeError as e: (logging.getLogger('locales') .error("Can't read file: " + file + '; ' + str(e))) - self.contents = u'' + self.contents = '' f.close() def readContents(self, contents): @@ -219,31 +219,31 @@ class DTDParser(Parser): # | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | # [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | # [#x10000-#xEFFFF] - CharMinusDash = u'\x09\x0A\x0D\u0020-\u002C\u002E-\uD7FF\uE000-\uFFFD' + CharMinusDash = '\x09\x0A\x0D\u0020-\u002C\u002E-\uD7FF\uE000-\uFFFD' XmlComment = '' % CharMinusDash - NameStartChar = u':A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF' + \ - u'\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F' + \ - u'\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD' + NameStartChar = ':A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF' + \ + '\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F' + \ + '\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD' # + \U00010000-\U000EFFFF seems to be unsupported in python # NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | # [#x0300-#x036F] | [#x203F-#x2040] - NameChar = NameStartChar + ur'\-\.0-9' + u'\xB7\u0300-\u036F\u203F-\u2040' + NameChar = NameStartChar + urr'\-\.0-9' + '\xB7\u0300-\u036F\u203F-\u2040' Name = '[' + NameStartChar + '][' + NameChar + ']*' - reKey = re.compile('(?:(?P
\s*)(?P(?:' + XmlComment +
-                       '\s*)*)(?P' + Name +
-                       ')\s+(?P\"[^\"]*\"|\'[^\']*\'?)\s*>)'
-                       '(?P[ \t]*(?:' + XmlComment + '\s*)*\n?)?)',
+    reKey = re.compile(r'(?:(?P
\s*)(?P(?:' + XmlComment +
+                       r'\s*)*)(?P' + Name +
+                       ')\\s+(?P\"[^\"]*\"|\'[^\']*\'?)\\s*>)'
+                       '(?P[ \t]*(?:' + XmlComment + '\\s*)*\n?)?)',
                        re.DOTALL)
     # add BOM to DTDs, details in bug 435002
-    reHeader = re.compile(u'^\ufeff?'
-                          u'(\s*)?', re.S)
-    reFooter = re.compile('\s*(\s*)*$')
-    rePE = re.compile('(?:(\s*)((?:' + XmlComment + '\s*)*)'
-                      '(\s*%' + Name +
-                      ';)([ \t]*(?:' + XmlComment + '\s*)*\n?)?)')
+    reHeader = re.compile('^\ufeff?'
+                          r'(\s*)?', re.S)
+    reFooter = re.compile(r'\s*(\s*)*$')
+    rePE = re.compile(r'(?:(\s*)((?:' + XmlComment + r'\s*)*)'
+                      r'(\\s*%' + Name +
+                      ';)([ \t]*(?:' + XmlComment + '\\s*)*\n?)?)')
 
     def getEntity(self, contents, offset):
         '''
@@ -273,15 +273,15 @@ class DTDParser(Parser):
 
 class PropertiesParser(Parser):
     escape = re.compile(r'\\((?Pu[0-9a-fA-F]{1,4})|'
-                        '(?P\n\s*)|(?P.))', re.M)
+                        '(?P\n\\s*)|(?P.))', re.M)
     known_escapes = {'n': '\n', 'r': '\r', 't': '\t', '\\': '\\'}
 
     def __init__(self):
-        self.reKey = re.compile('^(\s*)'
-                                '((?:[#!].*?\n\s*)*)'
-                                '([^#!\s\n][^=:\n]*?)\s*[:=][ \t]*', re.M)
-        self.reHeader = re.compile('^\s*([#!].*\s*)+')
-        self.reFooter = re.compile('\s*([#!].*\s*)*$')
+        self.reKey = re.compile(r'^(\s*)'
+                                '((?:[#!].*?\n\\s*)*)'
+                                '([^#!\\s\n][^=:\n]*?)\\s*[:=][ \t]*', re.M)
+        self.reHeader = re.compile(r'^\s*([#!].*\s*)+')
+        self.reFooter = re.compile(r'\s*([#!].*\s*)*$')
         self._escapedEnd = re.compile(r'\\+$')
         self._trailingWS = re.compile(r'[ \t]*$')
         Parser.__init__(self)
@@ -354,11 +354,11 @@ class DefinesParser(Parser):
     canMerge = False
 
     def __init__(self):
-        self.reKey = re.compile('^(\s*)((?:^#(?!define\s).*\s*)*)'
-                                '(#define[ \t]+(\w+)[ \t]+(.*?))([ \t]*$\n?)',
+        self.reKey = re.compile(r'^(\s*)((?:^#(?!define\s).*\s*)*)'
+                                '(#define[ \t]+(\\w+)[ \t]+(.*?))([ \t]*$\n?)',
                                 re.M)
-        self.reHeader = re.compile('^\s*(#(?!define\s).*\s*)*')
-        self.reFooter = re.compile('\s*(#(?!define\s).*\s*)*$', re.M)
+        self.reHeader = re.compile(r'^\s*(#(?!define\s).*\s*)*')
+        self.reFooter = re.compile(r'\s*(#(?!define\s).*\s*)*$', re.M)
         Parser.__init__(self)
 
 
@@ -373,9 +373,9 @@ class IniParser(Parser):
     ...
     '''
     def __init__(self):
-        self.reHeader = re.compile('^((?:\s*|[;#].*)\n)*\[.+?\]\n', re.M)
-        self.reKey = re.compile('(\s*)((?:[;#].*\n\s*)*)((.+?)=(.*))(\n?)')
-        self.reFooter = re.compile('\s*([;#].*\s*)*$')
+        self.reHeader = re.compile('^((?:\\s*|[;#].*)\n)*\\[.+?\\]\n', re.M)
+        self.reKey = re.compile('(\\s*)((?:[;#].*\n\\s*)*)((.+?)=(.*))(\n?)')
+        self.reFooter = re.compile(r'\s*([;#].*\s*)*$')
         Parser.__init__(self)
 
 
diff --git a/python/compare-locales/compare_locales/paths.py b/python/compare-locales/compare_locales/paths.py
index f72b3a2e72..0ee4eb36c9 100644
--- a/python/compare-locales/compare_locales/paths.py
+++ b/python/compare-locales/compare_locales/paths.py
@@ -4,15 +4,15 @@
 
 import os.path
 import os
-from ConfigParser import ConfigParser, NoSectionError, NoOptionError
-from urlparse import urlparse, urljoin
-from urllib import pathname2url, url2pathname
-from urllib2 import urlopen
+from configparser import ConfigParser, NoSectionError, NoOptionError
+from urllib.parse import urlparse, urljoin
+from urllib.request import pathname2url, url2pathname
+from urllib.request import urlopen
 from collections import defaultdict
 from compare_locales import util
 
 
-class L10nConfigParser(object):
+class L10nConfigParser:
     '''Helper class to gather application information from ini files.
 
     This class is working on synchronous open to read files or web data.
@@ -58,7 +58,7 @@ class L10nConfigParser(object):
         filterurl = urljoin(self.inipath, 'filter.py')
         try:
             l = {}
-            execfile(url2pathname(urlparse(filterurl).path), {}, l)
+            exec(compile(open(url2pathname(urlparse(filterurl).path), "rb").read(), url2pathname(urlparse(filterurl).path), 'exec'), {}, l)
             if 'test' in l and callable(l['test']):
                 filters = [l['test']]
             else:
@@ -151,11 +151,9 @@ class L10nConfigParser(object):
         """Iterate over all dirs and base paths for this l10n.ini as well
         as the included ones.
         """
-        for t in self.dirsIter():
-            yield t
+        yield from self.dirsIter()
         for child in self.children:
-            for t in child.directories():
-                yield t
+            yield from child.directories()
 
     def allLocales(self):
         """Return a list of all the locales of this project"""
@@ -214,7 +212,7 @@ class SourceTreeConfigParser(L10nConfigParser):
         return (basepath, )
 
 
-class File(object):
+class File:
 
     def __init__(self, fullpath, file, module=None, locale=None):
         self.fullpath = fullpath
@@ -225,7 +223,7 @@ class File(object):
 
     def getContents(self):
         # open with universal line ending support and read
-        return open(self.fullpath, 'rU').read()
+        return open(self.fullpath).read()
 
     def __hash__(self):
         f = self.file
@@ -245,7 +243,7 @@ class File(object):
         return cmp(self.file, other.file)
 
 
-class EnumerateDir(object):
+class EnumerateDir:
     ignore_dirs = ['CVS', '.svn', '.hg', '.git']
 
     def __init__(self, basepath, module='', locale=None, ignore_subdirs=[]):
@@ -287,7 +285,7 @@ class EnumerateDir(object):
                            self.module, self.locale)
 
 
-class LocalesWrap(object):
+class LocalesWrap:
 
     def __init__(self, base, module, locales, ignore_subdirs=[]):
         self.base = base
@@ -302,7 +300,7 @@ class LocalesWrap(object):
                                         self.ignore_subdirs))
 
 
-class EnumerateApp(object):
+class EnumerateApp:
     reference = 'en-US'
 
     def __init__(self, inipath, l10nbase, locales=None):
@@ -355,7 +353,7 @@ class EnumerateApp(object):
         code and an directory enumerator will be given.
         '''
         dirmap = dict(self.config.directories())
-        mods = dirmap.keys()
+        mods = list(dirmap.keys())
         mods.sort()
         for mod in mods:
             if self.reference == 'en-US':
diff --git a/python/compare-locales/compare_locales/tests/__init__.py b/python/compare-locales/compare_locales/tests/__init__.py
index 8808d78f4c..458a14bc10 100644
--- a/python/compare-locales/compare_locales/tests/__init__.py
+++ b/python/compare-locales/compare_locales/tests/__init__.py
@@ -5,11 +5,12 @@
 '''Mixins for parser tests.
 '''
 
-from itertools import izip_longest
+
 from pkg_resources import resource_string
 import re
 
 from compare_locales.parser import getParser
+from itertools import zip_longest
 
 
 class ParserTestMixin():
@@ -39,7 +40,7 @@ class ParserTestMixin():
         '''
         self.parser.readContents(content)
         entities = [entity for entity in self.parser]
-        for entity, ref in izip_longest(entities, refs):
+        for entity, ref in zip_longest(entities, refs):
             self.assertTrue(entity, 'excess reference entity')
             self.assertTrue(ref, 'excess parsed entity')
             self.assertEqual(entity.val, ref[1])
diff --git a/python/compare-locales/compare_locales/tests/test_checks.py b/python/compare-locales/compare_locales/tests/test_checks.py
index b995d43f90..0b43f2ddb9 100644
--- a/python/compare-locales/compare_locales/tests/test_checks.py
+++ b/python/compare-locales/compare_locales/tests/test_checks.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
@@ -111,9 +110,9 @@ class TestDTDs(BaseHelper):
                    (('warning', (0, 0), 'Referencing unknown entity `not`',
                      'xmlparse'),))
         # make sure we only handle translated entity references
-        self._test(u'''
+        self._test('''
 '''.encode('utf-8'),
-            (('warning', (0, 0), u'Referencing unknown entity `ƞǿŧ`',
+            (('warning', (0, 0), 'Referencing unknown entity `ƞǿŧ`',
               'xmlparse'),))
 
     def testErrorFirstLine(self):
@@ -233,10 +232,10 @@ class TestAndroid(unittest.TestCase):
     Make sure we're hitting our extra rules only if
     we're passing in a DTD file in the embedding/android module.
     """
-    apos_msg = u"Apostrophes in Android DTDs need escaping with \\' or " + \
-               u"\\u0027, or use \u2019, or put string in quotes."
-    quot_msg = u"Quotes in Android DTDs need escaping with \\\" or " + \
-               u"\\u0022, or put string in apostrophes."
+    apos_msg = "Apostrophes in Android DTDs need escaping with \\' or " + \
+               "\\u0027, or use \u2019, or put string in quotes."
+    quot_msg = "Quotes in Android DTDs need escaping with \\\" or " + \
+               "\\u0022, or put string in apostrophes."
 
     def getEntity(self, v):
         return Entity(v, lambda s: s, (0, len(v)), (), (0, 0), (), (),
@@ -267,7 +266,7 @@ class TestAndroid(unittest.TestCase):
                          (('warning', (0, 0),
                            'Referencing unknown entity `ref`', 'xmlparse'),))
         # no report on stray ampersand or quote, if not completely quoted
-        for i in xrange(3):
+        for i in range(3):
             # make sure we're catching unescaped apostrophes,
             # try 0..5 backticks
             l10n = self.getDTDEntity("\\"*(2*i) + "'")
@@ -323,7 +322,7 @@ class TestAndroid(unittest.TestCase):
                          (('error', 12, 'truncated \\uXXXX escape',
                            'android'),))
         # broken unicode escape, try to set the error off
-        l10n = self.getDTDEntity(u"\u9690"*14+"\u006"+"  "+"\u0064")
+        l10n = self.getDTDEntity("\u9690"*14+"\u006"+"  "+"\u0064")
         self.assertEqual(tuple(checker.check(ref, l10n)),
                          (('error', 14, 'truncated \\uXXXX escape',
                            'android'),))
diff --git a/python/compare-locales/compare_locales/tests/test_dtd.py b/python/compare-locales/compare_locales/tests/test_dtd.py
index 87ddcde301..cc8a642c88 100644
--- a/python/compare-locales/compare_locales/tests/test_dtd.py
+++ b/python/compare-locales/compare_locales/tests/test_dtd.py
@@ -47,7 +47,7 @@ class TestDTD(ParserTestMixin, unittest.TestCase):
             return qr.sub(lambda m: m.group(0) == '"' and "'" or '"', s)
 
         self._test(quot2apos(self.quoteContent),
-                   map(lambda t: (t[0], quot2apos(t[1])), self.quoteRef))
+                   [(t[0], quot2apos(t[1])) for t in self.quoteRef])
 
     def test_parsed_ref(self):
         self._test('''
@@ -70,7 +70,7 @@ class TestDTD(ParserTestMixin, unittest.TestCase):
         for e in p:
             self.assertEqual(e.key, 'foo')
             self.assertEqual(e.val, 'value')
-        self.assert_('MPL' in p.header)
+        self.assertTrue('MPL' in p.header)
         p.readContents('''\
  ABC DEF Gxx"
         args = [iter(iterable)] * n
-        return itertools.izip_longest(fillvalue=dummy_fill_value, *args)
+        return itertools.zip_longest(fillvalue=dummy_fill_value, *args)
 
     for i, unified_group in enumerate(grouper(files_per_unified_file,
                                               files)):
@@ -1104,10 +1110,10 @@ def pair(iterable):
         [(1,2), (3,4), (5,6)]
     '''
     i = iter(iterable)
-    return itertools.izip_longest(i, i)
+    return itertools.zip_longest(i, i)
 
 
-VARIABLES_RE = re.compile('\$\((\w+)\)')
+VARIABLES_RE = re.compile(r'\$\((\w+)\)')
 
 
 def expand_variables(s, variables):
@@ -1122,7 +1128,7 @@ def expand_variables(s, variables):
         value = variables.get(name)
         if not value:
             continue
-        if not isinstance(value, types.StringTypes):
+        if not isinstance(value, (str,)):
             value = ' '.join(value)
         result += value
     return result
@@ -1149,7 +1155,7 @@ class EnumStringComparisonError(Exception):
     pass
 
 
-class EnumString(unicode):
+class EnumString(str):
     '''A string type that only can have a limited set of values, similarly to
     an Enum, and can only be compared against that set of values.
 
@@ -1165,14 +1171,15 @@ class EnumString(unicode):
 
     def __eq__(self, other):
         if other not in self.POSSIBLE_VALUES:
-            raise EnumStringComparisonError(
-                'Can only compare with %s'
-                % ', '.join("'%s'" % v for v in self.POSSIBLE_VALUES))
+            return False
         return super(EnumString, self).__eq__(other)
 
     def __ne__(self, other):
         return not (self == other)
 
+    # Restore hash since we define __eq__
+    __hash__ = str.__hash__
+
     @staticmethod
     def subclass(*possible_values):
         class EnumStringSubclass(EnumString):
@@ -1181,23 +1188,23 @@ class EnumString(unicode):
 
 
 def _escape_char(c):
-    # str.encode('unicode_espace') doesn't escape quotes, presumably because
+    # str.encode('unicode_escape') doesn't escape quotes, presumably because
     # quoting could be done with either ' or ".
     if c == "'":
         return "\\'"
-    return unicode(c.encode('unicode_escape'))
+    # In Python 3, encode returns bytes; decode to get the escape sequence string
+    return c.encode('unicode_escape').decode('ascii')
 
 # Mapping table between raw characters below \x80 and their escaped
 # counterpart, when they differ
 _INDENTED_REPR_TABLE = {
     c: e
-    for c, e in map(lambda x: (x, _escape_char(x)),
-                    map(unichr, range(128)))
+    for c, e in [(x, _escape_char(x)) for x in list(map(chr, list(range(128))))]
     if c != e
 }
 # Regexp matching all characters to escape.
 _INDENTED_REPR_RE = re.compile(
-    '([' + ''.join(_INDENTED_REPR_TABLE.values()) + ']+)')
+    '([' + ''.join(list(_INDENTED_REPR_TABLE.values())) + ']+)')
 
 
 def indented_repr(o, indent=4):
@@ -1223,7 +1230,7 @@ def indented_repr(o, indent=4):
         elif isinstance(o, bytes):
             yield 'b'
             yield repr(o)
-        elif isinstance(o, unicode):
+        elif isinstance(o, str):
             yield "'"
             # We want a readable string (non escaped unicode), but some
             # special characters need escaping (e.g. \n, \t, etc.)
@@ -1253,11 +1260,11 @@ def encode(obj, encoding='utf-8'):
     if isinstance(obj, dict):
         return {
             encode(k, encoding): encode(v, encoding)
-            for k, v in obj.iteritems()
+            for k, v in obj.items()
         }
     if isinstance(obj, bytes):
         return obj
-    if isinstance(obj, unicode):
+    if isinstance(obj, str):
         return obj.encode(encoding)
     if isinstance(obj, Iterable):
         return [encode(i, encoding) for i in obj]
diff --git a/python/mozbuild/mozbuild/vendor_rust.py b/python/mozbuild/mozbuild/vendor_rust.py
index 92103e1cb1..96e1ed0474 100644
--- a/python/mozbuild/mozbuild/vendor_rust.py
+++ b/python/mozbuild/mozbuild/vendor_rust.py
@@ -2,9 +2,28 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import, print_function, unicode_literals
 
-from distutils.version import LooseVersion
+import re
+class LooseVersion:
+    """Simple version comparison (replacement for distutils.version.LooseVersion)."""
+    def __init__(self, vstring):
+        self.vstring = vstring
+        self.version = [int(x) if x.isdigit() else x for x in re.split(r'[.\-]', vstring)]
+    def __str__(self): return self.vstring
+    def __repr__(self): return "LooseVersion('%s')" % self.vstring
+    def _cmp(self, other):
+        if not isinstance(other, LooseVersion):
+            other = LooseVersion(str(other))
+        try:
+            if self.version == other.version: return 0
+            if self.version < other.version: return -1
+            return 1
+        except TypeError: return -1
+    def __lt__(self, o): return self._cmp(o) < 0
+    def __le__(self, o): return self._cmp(o) <= 0
+    def __eq__(self, o): return self._cmp(o) == 0
+    def __ge__(self, o): return self._cmp(o) >= 0
+    def __gt__(self, o): return self._cmp(o) > 0
 import logging
 from mozbuild.base import (
     BuildEnvironmentNotFoundException,
diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
index 05d30424b8..a691745d44 100644
--- a/python/mozbuild/mozbuild/virtualenv.py
+++ b/python/mozbuild/mozbuild/virtualenv.py
@@ -5,24 +5,50 @@
 # This file contains code for populating the virtualenv environment for
 # Mozilla's build system. It is typically called as part of configure.
 
-from __future__ import absolute_import, print_function, unicode_literals
 
-import distutils.sysconfig
+import sysconfig
 import os
 import shutil
 import subprocess
 import sys
 import warnings
 
-from distutils.version import LooseVersion
+try:
+    from distutils.version import LooseVersion
+except ImportError:
+    import re as _re
+    class LooseVersion:
+        def __init__(self, vstring):
+            self.vstring = vstring
+            self.version = [int(x) if x.isdigit() else x
+                            for x in _re.split(r'[.\-]', vstring)]
+        def __str__(self): return self.vstring
+        def __repr__(self): return "LooseVersion ('%s')" % str(self)
+        def _cmp(self, other):
+            if not isinstance(other, LooseVersion):
+                other = LooseVersion(other)
+            a, b = self.version, other.version
+            for i in range(max(len(a), len(b))):
+                va = a[i] if i < len(a) else 0
+                vb = b[i] if i < len(b) else 0
+                if type(va) != type(vb):
+                    va, vb = str(va), str(vb)
+                if va < vb: return -1
+                if va > vb: return 1
+            return 0
+        def __eq__(self, other): return self._cmp(other) == 0
+        def __lt__(self, other): return self._cmp(other) < 0
+        def __le__(self, other): return self._cmp(other) <= 0
+        def __gt__(self, other): return self._cmp(other) > 0
+        def __ge__(self, other): return self._cmp(other) >= 0
 
 IS_NATIVE_WIN = (sys.platform == 'win32' and os.sep == '\\')
 IS_MSYS2 = (sys.platform == 'win32' and os.sep == '/')
 IS_CYGWIN = (sys.platform == 'cygwin')
 
 # Minimum version of Python required to build.
-MINIMUM_PYTHON_VERSION = LooseVersion('2.7.3')
-MINIMUM_PYTHON_MAJOR = 2
+MINIMUM_PYTHON_VERSION = LooseVersion('3.6.0')
+MINIMUM_PYTHON_MAJOR = 3
 
 
 UPGRADE_WINDOWS = '''
@@ -39,7 +65,7 @@ defined by the $PATH environment variable and try again.
 '''.lstrip()
 
 
-class VirtualenvManager(object):
+class VirtualenvManager:
     """Contains logic for managing virtualenvs for building the tree."""
 
     def __init__(self, topsrcdir, topobjdir, virtualenv_path, log_handle,
@@ -90,13 +116,17 @@ class VirtualenvManager(object):
 
     @property
     def activate_path(self):
-        return os.path.join(self.bin_path, 'activate_this.py')
+        # Python's venv uses 'activate', not 'activate_this.py'
+        activate_this = os.path.join(self.bin_path, 'activate_this.py')
+        if os.path.exists(activate_this):
+            return activate_this
+        return os.path.join(self.bin_path, 'activate')
 
     def get_exe_info(self):
         """Returns the version and file size of the python executable that was in
         use when this virutalenv was created.
         """
-        with open(self.exe_info_path, 'r') as fh:
+        with open(self.exe_info_path) as fh:
             version, size = fh.read().splitlines()
         return int(version), int(size)
 
@@ -106,7 +136,7 @@ class VirtualenvManager(object):
         on OS X our python path may end up being a different or modified
         executable.
         """
-        ver = subprocess.check_output([python, '-c', 'import sys; print(sys.hexversion)']).rstrip()
+        ver = subprocess.check_output([python, '-c', 'import sys; print(sys.hexversion)']).rstrip().decode('utf-8')
         with open(self.exe_info_path, 'w') as fh:
             fh.write("%s\n" % ver)
             fh.write("%s\n" % os.path.getsize(python))
@@ -181,20 +211,13 @@ class VirtualenvManager(object):
     def create(self, python=sys.executable):
         """Create a new, empty virtualenv.
 
-        Receives the path to virtualenv's virtualenv.py script (which will be
-        called out to), the path to create the virtualenv in, and a handle to
-        write output to.
+        Uses Python 3's built-in venv module instead of the old virtualenv.py.
         """
         env = dict(os.environ)
         env.pop('PYTHONDONTWRITEBYTECODE', None)
 
-        args = [python, self.virtualenv_script_path,
-            # Without this, virtualenv.py may attempt to contact the outside
-            # world and search for or download a newer version of pip,
-            # setuptools, or wheel. This is bad for security, reproducibility,
-            # and speed.
-            '--no-download',
-            self.virtualenv_root]
+        # Use Python's built-in venv (available since Python 3.3)
+        args = [python, '-m', 'venv', '--without-pip', self.virtualenv_root]
 
         result = self._log_process_output(args, env=env)
 
@@ -207,7 +230,7 @@ class VirtualenvManager(object):
         return self.virtualenv_root
 
     def packages(self):
-        with file(self.manifest_path, 'rU') as fh:
+        with open(self.manifest_path, 'r') as fh:
             packages = [line.rstrip().split(':')
                         for line in fh]
         return packages
@@ -252,7 +275,7 @@ class VirtualenvManager(object):
         """
 
         packages = self.packages()
-        python_lib = distutils.sysconfig.get_python_lib()
+        python_lib = sysconfig.get_path('purelib')
 
         def handle_package(package):
             if package[0] == 'setup.py':
@@ -347,7 +370,7 @@ class VirtualenvManager(object):
         try:
             old_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
             sysconfig_target = \
-                distutils.sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+                sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
 
             if sysconfig_target is not None:
                 os.environ['MACOSX_DEPLOYMENT_TARGET'] = sysconfig_target
@@ -390,8 +413,7 @@ class VirtualenvManager(object):
             for package in packages:
                 handle_package(package)
 
-            sitecustomize = os.path.join(
-                os.path.dirname(os.__file__), 'sitecustomize.py')
+            sitecustomize = os.path.join(python_lib, 'sitecustomize.py')
             with open(sitecustomize, 'w') as f:
                 f.write(
                     '# Importing mach_bootstrap has the side effect of\n'
@@ -461,9 +483,7 @@ class VirtualenvManager(object):
         and call .ensure() and .activate() to make the virtualenv active.
         """
 
-        execfile(self.activate_path, dict(__file__=self.activate_path))
-        if isinstance(os.environ['PATH'], unicode):
-            os.environ['PATH'] = os.environ['PATH'].encode('utf-8')
+        exec(open(self.activate_path).read(), {"__file__": self.activate_path})
 
     def install_pip_package(self, package):
         """Install a package via pip.
@@ -531,7 +551,7 @@ def verify_python_version(log_handle):
     our = LooseVersion('%d.%d.%d' % (major, minor, micro))
 
     if major != MINIMUM_PYTHON_MAJOR or our < MINIMUM_PYTHON_VERSION:
-        log_handle.write('Python %s or greater (but not Python 3) is '
+        log_handle.write('Python %s or greater is '
             'required to build. ' % MINIMUM_PYTHON_VERSION)
         log_handle.write('You are running Python %s.\n' % our)
 
diff --git a/python/mozbuild/mozpack/archive.py b/python/mozbuild/mozpack/archive.py
index f3015ff21c..f1ea17f5a2 100644
--- a/python/mozbuild/mozpack/archive.py
+++ b/python/mozbuild/mozpack/archive.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import bz2
 import gzip
@@ -73,7 +72,7 @@ def create_tar_gz_from_files(fp, files, filename=None, compresslevel=9):
         create_tar_from_files(gf, files)
 
 
-class _BZ2Proxy(object):
+class _BZ2Proxy:
     """File object that proxies writes to a bz2 compressor."""
     def __init__(self, fp, compresslevel=9):
         self.fp = fp
diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py
index 8c5c9a54c0..40c3fa9d80 100644
--- a/python/mozbuild/mozpack/chrome/flags.py
+++ b/python/mozbuild/mozpack/chrome/flags.py
@@ -2,15 +2,33 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import re
-from distutils.version import LooseVersion
+class LooseVersion:
+    """Simple version comparison (replacement for distutils.version.LooseVersion)."""
+    def __init__(self, vstring):
+        self.vstring = vstring
+        self.version = [int(x) if x.isdigit() else x for x in re.split(r'[.\-]', vstring)]
+    def __str__(self): return self.vstring
+    def __repr__(self): return "LooseVersion('%s')" % self.vstring
+    def _cmp(self, other):
+        if not isinstance(other, LooseVersion):
+            other = LooseVersion(str(other))
+        try:
+            if self.version == other.version: return 0
+            if self.version < other.version: return -1
+            return 1
+        except TypeError: return -1
+    def __lt__(self, o): return self._cmp(o) < 0
+    def __le__(self, o): return self._cmp(o) <= 0
+    def __eq__(self, o): return self._cmp(o) == 0
+    def __ge__(self, o): return self._cmp(o) >= 0
+    def __gt__(self, o): return self._cmp(o) > 0
 from mozpack.errors import errors
 from collections import OrderedDict
 
 
-class Flag(object):
+class Flag:
     '''
     Class for flags in manifest entries in the form:
         "flag"   (same as "flag=true")
@@ -60,10 +78,10 @@ class Flag(object):
             return ''
         if self.value is True:
             return self.name
-        return '%s=%s' % (self.name, self.value)
+        return '{}={}'.format(self.name, self.value)
 
 
-class StringFlag(object):
+class StringFlag:
     '''
     Class for string flags in manifest entries in the form:
         "flag=string"
@@ -120,13 +138,13 @@ class StringFlag(object):
         res = []
         for comparison, val in self.values:
             if comparison == '==':
-                res.append('%s=%s' % (self.name, val))
+                res.append('{}={}'.format(self.name, val))
             else:
-                res.append('%s!=%s' % (self.name, val))
+                res.append('{}!={}'.format(self.name, val))
         return ' '.join(res)
 
 
-class VersionFlag(object):
+class VersionFlag:
     '''
     Class for version flags in manifest entries in the form:
         "flag=version"
@@ -193,9 +211,9 @@ class VersionFlag(object):
         res = []
         for comparison, val in self.values:
             if comparison == '==':
-                res.append('%s=%s' % (self.name, val))
+                res.append('{}={}'.format(self.name, val))
             else:
-                res.append('%s%s%s' % (self.name, comparison, val))
+                res.append('{}{}{}'.format(self.name, comparison, val))
         return ' '.join(res)
 
 
@@ -250,7 +268,7 @@ class Flags(OrderedDict):
             flags.match(application='foo', appversion='3.5') returns True
             flags.match(application='foo', appversion='3.0') returns False
         '''
-        for name, value in filter.iteritems():
+        for name, value in filter.items():
             if not name in self:
                 continue
             if not self[name].matches(value):
diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py
index 71241764da..4644bb2a19 100644
--- a/python/mozbuild/mozpack/chrome/manifest.py
+++ b/python/mozbuild/mozpack/chrome/manifest.py
@@ -2,17 +2,16 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import re
 import os
-from urlparse import urlparse
+from urllib.parse import urlparse
 import mozpack.path as mozpath
 from mozpack.chrome.flags import Flags
 from mozpack.errors import errors
 
 
-class ManifestEntry(object):
+class ManifestEntry:
     '''
     Base class for all manifest entry types.
     Subclasses may define the following class or member variables:
@@ -68,7 +67,7 @@ class ManifestEntry(object):
         return not self.__eq__(other)
 
     def __repr__(self):
-        return '<%s@%s>' % (str(self), self.base)
+        return '<{}@{}>'.format(str(self), self.base)
 
     def move(self, base):
         '''
@@ -321,9 +320,9 @@ class ManifestContract(ManifestEntry):
         return self.serialize(self.contractID, self.cid)
 
 # All manifest classes by their type name.
-MANIFESTS_TYPES = dict([(c.type, c) for c in globals().values()
+MANIFESTS_TYPES = {c.type: c for c in globals().values()
                        if type(c) == type and issubclass(c, ManifestEntry)
-                       and hasattr(c, 'type') and c.type])
+                       and hasattr(c, 'type') and c.type}
 
 MANIFEST_RE = re.compile(r'^#.*$')
 
@@ -354,6 +353,8 @@ def parse_manifest(root, path, fileobj=None):
     linenum = 0
     for line in fileobj:
         linenum += 1
+        if isinstance(line, bytes):
+            line = line.decode('utf-8', errors='replace')
         with errors.context(path, linenum):
             e = parse_manifest_line(base, line)
             if e:
diff --git a/python/mozbuild/mozpack/copier.py b/python/mozbuild/mozpack/copier.py
index 15c550e7ba..60d653fba6 100644
--- a/python/mozbuild/mozpack/copier.py
+++ b/python/mozbuild/mozpack/copier.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import os
 import stat
@@ -22,7 +21,7 @@ from collections import (
 import concurrent.futures as futures
 
 
-class FileRegistry(object):
+class FileRegistry:
     '''
     Generic container to keep track of a set of BaseFile instances. It
     preserves the order under which the files are added, but doesn't keep
@@ -99,7 +98,7 @@ class FileRegistry(object):
         '''
         items = self.match(pattern)
         if not items:
-            return errors.error("Can't remove %s: %s" % (pattern,
+            return errors.error("Can't remove {}: {}".format(pattern,
                                 "not matching anything previously added"))
         for i in items:
             del self._files[i]
@@ -109,7 +108,7 @@ class FileRegistry(object):
         '''
         Return all paths stored in the container, in the order they were added.
         '''
-        return self._files.keys()
+        return list(self._files.keys())
 
     def __len__(self):
         '''
@@ -142,7 +141,7 @@ class FileRegistry(object):
             for path, file in registry:
                 (...)
         '''
-        return self._files.iteritems()
+        return iter(self._files.items())
 
     def required_directories(self):
         '''
@@ -151,10 +150,10 @@ class FileRegistry(object):
         unspecified (virtual) root directory (and do not include said root
         directory).
         '''
-        return set(k for k, v in self._required_directories.items() if v > 0)
+        return {k for k, v in self._required_directories.items() if v > 0}
 
 
-class FileRegistrySubtree(object):
+class FileRegistrySubtree:
     '''A proxy class to give access to a subtree of an existing FileRegistry.
 
     Note this doesn't implement the whole FileRegistry interface.'''
@@ -200,7 +199,7 @@ class FileRegistrySubtree(object):
                 yield mozpath.relpath(p, self._base), f
 
 
-class FileCopyResult(object):
+class FileCopyResult:
     """Represents results of a FileCopier.copy operation."""
 
     def __init__(self):
@@ -263,7 +262,7 @@ class FileCopier(FileRegistry):
 
         Returns a FileCopyResult that details what changed.
         '''
-        assert isinstance(destination, basestring)
+        assert isinstance(destination, str)
         assert not os.path.exists(destination) or os.path.isdir(destination)
 
         result = FileCopyResult()
@@ -286,9 +285,9 @@ class FileCopier(FileRegistry):
         # in Python over possibly I/O bound filesystem calls to stat() and
         # friends.
 
-        required_dirs = set([destination])
-        required_dirs |= set(os.path.normpath(os.path.join(destination, d))
-            for d in self.required_directories())
+        required_dirs = {destination}
+        required_dirs |= {os.path.normpath(os.path.join(destination, d))
+            for d in self.required_directories()}
 
         # Ensure destination directories are in place and proper.
         #
@@ -329,11 +328,11 @@ class FileCopier(FileRegistry):
                 os.chmod(d, 0o777 & ~umask)
 
         if isinstance(remove_unaccounted, FileRegistry):
-            existing_files = set(os.path.normpath(os.path.join(destination, p))
-                                 for p in remove_unaccounted.paths())
-            existing_dirs = set(os.path.normpath(os.path.join(destination, p))
+            existing_files = {os.path.normpath(os.path.join(destination, p))
+                                 for p in remove_unaccounted.paths()}
+            existing_dirs = {os.path.normpath(os.path.join(destination, p))
                                 for p in remove_unaccounted
-                                         .required_directories())
+                                         .required_directories()}
             existing_dirs |= {os.path.normpath(destination)}
         else:
             # While we have remove_unaccounted, it doesn't apply to empty
@@ -531,7 +530,7 @@ class Jarrer(FileRegistry, BaseFile):
             def exists(self):
                 return self.deflater is not None
 
-        if isinstance(dest, basestring):
+        if isinstance(dest, str):
             dest = Dest(dest)
         assert isinstance(dest, Dest)
 
@@ -541,7 +540,7 @@ class Jarrer(FileRegistry, BaseFile):
         except Exception:
             old_jar = []
 
-        old_contents = dict([(f.filename, f) for f in old_jar])
+        old_contents = {f.filename: f for f in old_jar}
 
         with JarWriter(fileobj=dest, compress=self.compress,
                        optimize=self.optimize) as jar:
diff --git a/python/mozbuild/mozpack/dmg.py b/python/mozbuild/mozpack/dmg.py
index 505cd8729e..fd10901e62 100644
--- a/python/mozbuild/mozpack/dmg.py
+++ b/python/mozbuild/mozpack/dmg.py
@@ -90,9 +90,9 @@ def check_tools(*tools):
         if not path:
             raise Exception('Required tool "%s" not found' % tool)
         if not os.path.isfile(path):
-            raise Exception('Required tool "%s" not found at path "%s"' % (tool, path))
+            raise Exception('Required tool "{}" not found at path "{}"'.format(tool, path))
         if not os.access(path, os.X_OK):
-            raise Exception('Required tool "%s" at path "%s" is not executable' % (tool, path))
+            raise Exception('Required tool "{}" at path "{}" is not executable'.format(tool, path))
 
 def create_dmg(source_directory, output_dmg, volume_name, extra_files):
     '''
diff --git a/python/mozbuild/mozpack/errors.py b/python/mozbuild/mozpack/errors.py
index 8b4b80072b..70867db89b 100644
--- a/python/mozbuild/mozpack/errors.py
+++ b/python/mozbuild/mozpack/errors.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import sys
 from contextlib import contextmanager
@@ -16,7 +15,7 @@ class AccumulatedErrors(Exception):
     '''Exception type raised from errors.accumulate()'''
 
 
-class ErrorCollector(object):
+class ErrorCollector:
     '''
     Error handling/logging class. A global instance, errors, is provided for
     convenience.
@@ -89,7 +88,7 @@ class ErrorCollector(object):
         if self._context:
             file, line = self._context[-1]
             return "%s: %s:%d: %s" % (level, file, line, msg)
-        return "%s: %s" % (level, msg)
+        return "{}: {}".format(level, msg)
 
     def _handle(self, level, msg):
         msg = self._full_message(level, msg)
@@ -97,7 +96,7 @@ class ErrorCollector(object):
             if self._count is None:
                 raise ErrorMessage(msg)
             self._count += 1
-        print >>self.out, msg
+        print(msg, file=self.out)
 
     def fatal(self, msg):
         self._handle(self.FATAL, msg)
diff --git a/python/mozbuild/mozpack/executables.py b/python/mozbuild/mozpack/executables.py
index 7a4fd0a0d3..68302154c8 100644
--- a/python/mozbuild/mozpack/executables.py
+++ b/python/mozbuild/mozpack/executables.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import os
 import struct
diff --git a/python/mozbuild/mozpack/files.py b/python/mozbuild/mozpack/files.py
index 6848e5ccc0..49a028cc7a 100644
--- a/python/mozbuild/mozpack/files.py
+++ b/python/mozbuild/mozpack/files.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import errno
 import os
@@ -57,7 +56,7 @@ else:
 
     def _copyfile(src, dest):
         # False indicates `dest` should be overwritten if it exists already.
-        if isinstance(src, unicode) and isinstance(dest, unicode):
+        if isinstance(src, str) and isinstance(dest, str):
             _CopyFileW(src, dest, False)
         elif isinstance(src, str) and isinstance(dest, str):
             _CopyFileA(src, dest, False)
@@ -145,13 +144,13 @@ class BaseFile(object):
         # - keep file type (e.g. S_IFREG)
         ret = stat.S_IFMT(mode)
         # - expand user read and execute permissions to everyone
-        if mode & 0400:
-            ret |= 0444
-        if mode & 0100:
-            ret |= 0111
+        if mode & 0o400:
+            ret |= 0o444
+        if mode & 0o100:
+            ret |= 0o111
         # - keep user write permissions
-        if mode & 0200:
-            ret |= 0200
+        if mode & 0o200:
+            ret |= 0o200
         # - leave away sticky bit, setuid, setgid
         return ret
 
@@ -164,7 +163,7 @@ class BaseFile(object):
         disabled when skip_if_older is False.
         Returns whether a copy was actually performed (True) or not (False).
         '''
-        if isinstance(dest, basestring):
+        if isinstance(dest, str):
             dest = Dest(dest)
         else:
             assert isinstance(dest, Dest)
@@ -185,12 +184,12 @@ class BaseFile(object):
             else:
                 # Ensure the file is always created
                 if not dest.exists():
-                    dest.write('')
+                    dest.write(b'')
                 shutil.copyfileobj(self.open(), dest)
             return True
 
         src = self.open()
-        copy_content = ''
+        copy_content = b''
         while True:
             dest_content = dest.read(32768)
             src_content = src.read(32768)
@@ -258,11 +257,11 @@ class ExecutableFile(File):
     '''
     def copy(self, dest, skip_if_older=True):
         real_dest = dest
-        if not isinstance(dest, basestring):
+        if not isinstance(dest, str):
             fd, dest = mkstemp()
             os.close(fd)
             os.remove(dest)
-        assert isinstance(dest, basestring)
+        assert isinstance(dest, str)
         # If File.copy didn't actually copy because dest is newer, check the
         # file sizes. If dest is smaller, it means it is already stripped and
         # elfhacked, so we can skip.
@@ -299,7 +298,7 @@ class AbsoluteSymlinkFile(File):
         File.__init__(self, path)
 
     def copy(self, dest, skip_if_older=True):
-        assert isinstance(dest, basestring)
+        assert isinstance(dest, str)
         from buildconfig import substs
 
         # The logic in this function is complicated by the fact that symlinks
@@ -402,7 +401,7 @@ class ExistingFile(BaseFile):
         self.required = required
 
     def copy(self, dest, skip_if_older=True):
-        if isinstance(dest, basestring):
+        if isinstance(dest, str):
             dest = Dest(dest)
         else:
             assert isinstance(dest, Dest)
@@ -434,7 +433,7 @@ class PreprocessedFile(BaseFile):
         '''
         Invokes the preprocessor to create the destination file.
         '''
-        if isinstance(dest, basestring):
+        if isinstance(dest, str):
             dest = Dest(dest)
         else:
             assert isinstance(dest, Dest)
@@ -497,7 +496,10 @@ class GeneratedFile(BaseFile):
         self.content = content
 
     def open(self):
-        return BytesIO(self.content)
+        content = self.content
+        if isinstance(content, str):
+            content = content.encode('utf-8')
+        return BytesIO(content)
 
 
 class DeflatedFile(BaseFile):
@@ -565,7 +567,7 @@ class XPTFile(GeneratedFile):
         the individual XPTs to link.
         skip_if_older is ignored.
         '''
-        if isinstance(dest, basestring):
+        if isinstance(dest, str):
             dest = Dest(dest)
         assert isinstance(dest, Dest)
 
@@ -644,7 +646,7 @@ class ManifestFile(BaseFile):
         the manifest.
         '''
         return BytesIO(''.join('%s\n' % e.rebase(self._base)
-                               for e in self._entries))
+                               for e in self._entries).encode('utf-8'))
 
     def __iter__(self):
         '''
@@ -1016,7 +1018,7 @@ class ComposedFinder(BaseFinder):
         from mozpack.copier import FileRegistry
         self.files = FileRegistry()
 
-        for base, finder in sorted(finders.iteritems()):
+        for base, finder in sorted(finders.items()):
             if self.files.contains(base):
                 self.files.remove(base)
             for p, f in finder.find(''):
diff --git a/python/mozbuild/mozpack/hg.py b/python/mozbuild/mozpack/hg.py
index 79876061f4..0d400ddca9 100644
--- a/python/mozbuild/mozpack/hg.py
+++ b/python/mozbuild/mozpack/hg.py
@@ -27,7 +27,6 @@
 # do not wish to do so, delete this exception statement from your
 # version.
 
-from __future__ import absolute_import
 
 import mercurial.error as error
 import mercurial.hg as hg
@@ -56,13 +55,13 @@ class MercurialNativeRevisionFinder(BaseFinder):
 
         Accepts a Mercurial localrepo and changectx instance.
         """
-        if isinstance(repo, (str, unicode)):
+        if isinstance(repo, (str, str)):
             path = repo
             repo = hg.repository(hgui.ui(), repo)
         else:
             path = repo.root
 
-        super(MercurialNativeRevisionFinder, self).__init__(base=repo.root)
+        super().__init__(base=repo.root)
 
         self._repo = repo
         self._rev = rev
@@ -85,7 +84,7 @@ class MercurialNativeRevisionFinder(BaseFinder):
         return self._get(path)
 
     def _get(self, path):
-        if isinstance(path, unicode):
+        if isinstance(path, str):
             path = path.encode('utf-8', 'replace')
 
         try:
diff --git a/python/mozbuild/mozpack/manifests.py b/python/mozbuild/mozpack/manifests.py
index b77931101a..1f80a345ee 100644
--- a/python/mozbuild/mozpack/manifests.py
+++ b/python/mozbuild/mozpack/manifests.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import, unicode_literals
 
 from contextlib import contextmanager
 import json
@@ -41,7 +40,7 @@ class UnreadableInstallManifest(Exception):
     """Raised when an invalid install manifest is parsed."""
 
 
-class InstallManifest(object):
+class InstallManifest:
     """Describes actions to be used with a copier.FileCopier instance.
 
     This class facilitates serialization and deserialization of data used to
@@ -115,7 +114,7 @@ class InstallManifest(object):
         self._source_files = set()
 
         if path or fileobj:
-            with _auto_fileobj(path, fileobj, 'rb') as fh:
+            with _auto_fileobj(path, fileobj, 'r') as fh:
                 self._source_files.add(fh.name)
                 self._load_from_fileobj(fh)
 
@@ -236,7 +235,7 @@ class InstallManifest(object):
 
         It is an error if both are specified.
         """
-        with _auto_fileobj(path, fileobj, 'wb') as fh:
+        with _auto_fileobj(path, fileobj, 'w') as fh:
             fh.write('%d\n' % self.CURRENT_VERSION)
 
             for dest in sorted(self._dests):
@@ -251,12 +250,12 @@ class InstallManifest(object):
                         source = mozpath.join(base, path)
                         parts = ['%d' % type, mozpath.join(dest, path), source]
                         fh.write('%s\n' % self.FIELD_SEPARATOR.join(
-                            p.encode('utf-8') for p in parts))
+                            p for p in parts))
                 else:
                     parts = ['%d' % entry[0], dest]
                     parts.extend(entry[1:])
                     fh.write('%s\n' % self.FIELD_SEPARATOR.join(
-                        p.encode('utf-8') for p in parts))
+                        p for p in parts))
 
     def add_symlink(self, source, dest):
         """Add a symlink to this manifest.
diff --git a/python/mozbuild/mozpack/mozjar.py b/python/mozbuild/mozpack/mozjar.py
index 2010a7f135..7d47b85230 100644
--- a/python/mozbuild/mozpack/mozjar.py
+++ b/python/mozbuild/mozpack/mozjar.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 from io import BytesIO
 import struct
@@ -14,9 +13,10 @@ from zipfile import (
     ZIP_DEFLATED,
 )
 from collections import OrderedDict
-from urlparse import urlparse, ParseResult
+from urllib.parse import urlparse, ParseResult
 import mozpack.path as mozpath
 from mozbuild.util import memoize
+from functools import reduce
 
 JAR_STORED = ZIP_STORED
 JAR_DEFLATED = ZIP_DEFLATED
@@ -71,7 +71,7 @@ class JarStruct(object):
         an instance with empty fields.
         '''
         assert self.MAGIC and isinstance(self.STRUCT, OrderedDict)
-        self.size_fields = set(t for t in self.STRUCT.itervalues()
+        self.size_fields = set(t for t in self.STRUCT.values()
                                if not t in JarStruct.TYPE_MAPPING)
         self._values = {}
         if data:
@@ -93,7 +93,7 @@ class JarStruct(object):
         # For all fields used as other fields sizes, keep track of their value
         # separately.
         sizes = dict((t, 0) for t in self.size_fields)
-        for name, t in self.STRUCT.iteritems():
+        for name, t in self.STRUCT.items():
             if t in JarStruct.TYPE_MAPPING:
                 value, size = JarStruct.get_data(t, data[offset:])
             else:
@@ -112,10 +112,10 @@ class JarStruct(object):
         Initialize an instance with empty fields.
         '''
         self.signature = self.MAGIC
-        for name, t in self.STRUCT.iteritems():
+        for name, t in self.STRUCT.items():
             if name in self.size_fields:
                 continue
-            self._values[name] = 0 if t in JarStruct.TYPE_MAPPING else ''
+            self._values[name] = 0 if t in JarStruct.TYPE_MAPPING else b''
 
     @staticmethod
     def get_data(type, data):
@@ -137,9 +137,9 @@ class JarStruct(object):
         from self.STRUCT.
         '''
         serialized = struct.pack('" % (self.__class__.__name__,
@@ -373,7 +376,7 @@ class JarReader(object):
         entries = self.entries
         if not entries:
             return JAR_STORED
-        return max(f['compression'] for f in entries.itervalues())
+        return max(f['compression'] for f in entries.values())
 
     @property
     def entries(self):
@@ -389,7 +392,7 @@ class JarReader(object):
             preload = JarStruct.get_data('uint32', self._data)[0]
         entries = OrderedDict()
         offset = self._cdir_end['cdir_offset']
-        for e in xrange(self._cdir_end['cdir_entries']):
+        for e in range(self._cdir_end['cdir_entries']):
             entry = JarCdirEntry(self._data[offset:])
             offset += entry.size
             # Creator host system. 0 is MSDOS, 3 is Unix
@@ -400,7 +403,7 @@ class JarReader(object):
             xattr = entry['external_attr']
             # Skip directories
             if (host == 0 and xattr & 0x10) or (host == 3 and
-                                                xattr & (040000 << 16)):
+                                                xattr & (0o40000 << 16)):
                 continue
             entries[entry['filename']] = entry
             if entry['offset'] < preload:
@@ -451,7 +454,7 @@ class JarReader(object):
             for file in jarReader:
                 ...
         '''
-        for entry in self.entries.itervalues():
+        for entry in self.entries.values():
             yield self._getreader(entry)
 
     def __getitem__(self, name):
@@ -546,7 +549,7 @@ class JarWriter(object):
         headers = {}
         preload_size = 0
         # Prepare central directory entries
-        for entry, content in self._contents.itervalues():
+        for entry, content in self._contents.values():
             header = JarLocalFileHeader()
             for name in entry.STRUCT:
                 if name in header:
@@ -561,7 +564,7 @@ class JarWriter(object):
         end['disk_entries'] = len(self._contents)
         end['cdir_entries'] = end['disk_entries']
         end['cdir_size'] = reduce(lambda x, y: x + y[0].size,
-                                  self._contents.values(), 0)
+                                  list(self._contents.values()), 0)
         # On optimized archives, store the preloaded size and the central
         # directory entries, followed by the first end of central directory.
         if self._optimize:
@@ -570,18 +573,18 @@ class JarWriter(object):
             if preload_size:
                 preload_size += offset
             self._data.write(struct.pack(' 1 else {}
         return component, options
@@ -118,11 +117,11 @@ class Component(object):
         destdir = options.pop('destdir', '')
         if options:
             errors.fatal('Malformed manifest: options %s not recognized'
-                         % options.keys())
+                         % list(options.keys()))
         return Component(name, destdir=destdir)
 
 
-class PackageManifestParser(object):
+class PackageManifestParser:
     '''
     Class for parsing of a package manifest, after preprocessing.
 
@@ -166,7 +165,7 @@ class PackageManifestParser(object):
             self._sink.add(self._component, str)
 
 
-class PreprocessorOutputWrapper(object):
+class PreprocessorOutputWrapper:
     '''
     File-like helper to handle the preprocessor output and send it to a parser.
     The parser's handle_line method is called in the relevant errors.context.
@@ -222,7 +221,7 @@ class CallDeque(deque):
                 function(*args)
 
 
-class SimplePackager(object):
+class SimplePackager:
     '''
     Helper used to translate and buffer instructions from the
     SimpleManifestSink to a formatter. Formatters expect some information to be
@@ -267,6 +266,8 @@ class SimplePackager(object):
             if mozpath.basename(path) == 'install.rdf':
                 addon = True
                 install_rdf = file.open().read()
+                if isinstance(install_rdf, bytes):
+                    install_rdf = install_rdf.decode('utf-8', errors='replace')
                 if self.UNPACK_ADDON_RE.search(install_rdf):
                     addon = 'unpacked'
                 self._addons[mozpath.dirname(path)] = addon
@@ -309,9 +310,9 @@ class SimplePackager(object):
         manifests are manifests that are included in no other manifest.
         `addons` indicates whether to include addon bases as well.
         '''
-        all_bases = set(mozpath.dirname(m)
+        all_bases = {mozpath.dirname(m)
                         for m in self._manifests
-                                 - set(self._included_manifests))
+                                 - set(self._included_manifests)}
         if not addons:
             all_bases -= set(self._addons)
         else:
@@ -328,7 +329,7 @@ class SimplePackager(object):
 
         bases = self.get_bases()
         broken_bases = sorted(
-            m for m, includer in self._included_manifests.iteritems()
+            m for m, includer in self._included_manifests.items()
             if mozpath.basedir(m, bases) != mozpath.basedir(includer, bases))
         for m in broken_bases:
             errors.fatal('"%s" is included from "%s", which is outside "%s"' %
@@ -341,7 +342,7 @@ class SimplePackager(object):
         self._file_queue.execute()
 
 
-class SimpleManifestSink(object):
+class SimpleManifestSink:
     '''
     Parser sink for "simple" package manifests. Simple package manifests use
     the format described in the PackageManifestParser documentation, but don't
diff --git a/python/mozbuild/mozpack/packager/formats.py b/python/mozbuild/mozpack/packager/formats.py
index 235fc3e90f..3442945b5f 100644
--- a/python/mozbuild/mozpack/packager/formats.py
+++ b/python/mozbuild/mozpack/packager/formats.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 from mozpack.chrome.manifest import (
     Manifest,
@@ -11,7 +10,7 @@ from mozpack.chrome.manifest import (
     ManifestBinaryComponent,
     ManifestResource,
 )
-from urlparse import urlparse
+from urllib.parse import urlparse
 import mozpack.path as mozpath
 from mozpack.files import (
     ManifestFile,
@@ -67,7 +66,7 @@ data.
 '''
 
 
-class PiecemealFormatter(object):
+class PiecemealFormatter:
     '''
     Generic formatter that dispatches across different sub-formatters
     according to paths.
@@ -89,7 +88,7 @@ class PiecemealFormatter(object):
         Return the deepest base directory containing the given path.
         '''
         self._frozen_bases = True
-        base = mozpath.basedir(path, self._sub_formatter.keys())
+        base = mozpath.basedir(path, list(self._sub_formatter.keys()))
         relpath = mozpath.relpath(path, base) if base else path
         return base, relpath
 
@@ -126,7 +125,7 @@ class FlatFormatter(PiecemealFormatter):
             FileRegistrySubtree(base, self.copier))
 
 
-class FlatSubFormatter(object):
+class FlatSubFormatter:
     '''
     Sub-formatter for the flat package format.
     '''
diff --git a/python/mozbuild/mozpack/packager/l10n.py b/python/mozbuild/mozpack/packager/l10n.py
index e3e05fc894..3604168454 100644
--- a/python/mozbuild/mozpack/packager/l10n.py
+++ b/python/mozbuild/mozpack/packager/l10n.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 '''
 Replace localized parts of a packaged directory with data from a langpack
@@ -42,12 +41,12 @@ from mozpack.packager.unpack import UnpackFinder
 from createprecomplete import generate_precomplete
 
 
-class LocaleManifestFinder(object):
+class LocaleManifestFinder:
     def __init__(self, finder):
         entries = self.entries = []
         bases = self.bases = []
 
-        class MockFormatter(object):
+        class MockFormatter:
             def add_interfaces(self, path, content):
                 pass
 
@@ -66,7 +65,7 @@ class LocaleManifestFinder(object):
         # Those type of entries are used by language packs to work as addons,
         # but are not necessary for the purpose of l10n repacking. So we wrap
         # the finder in order to remove those entries.
-        class WrapFinder(object):
+        class WrapFinder:
             def __init__(self, finder):
                 self._finder = finder
 
@@ -88,8 +87,8 @@ class LocaleManifestFinder(object):
         sink.close(False)
 
         # Find unique locales used in these manifest entries.
-        self.locales = list(set(e.id for e in self.entries
-                                if isinstance(e, ManifestLocale)))
+        self.locales = list({e.id for e in self.entries
+                                if isinstance(e, ManifestLocale)})
 
 
 def _repack(app_finder, l10n_finder, copier, formatter, non_chrome=set()):
@@ -140,8 +139,8 @@ def _repack(app_finder, l10n_finder, copier, formatter, non_chrome=set()):
     for pattern in non_chrome:
         for base in app.bases:
             path = mozpath.join(base, pattern)
-            left = set(p for p, f in app_finder.find(path))
-            right = set(p for p, f in l10n_finder.find(path))
+            left = {p for p, f in app_finder.find(path)}
+            right = {p for p, f in l10n_finder.find(path)}
             for p in right:
                 paths[p] = p
             for p in left - right:
@@ -163,7 +162,7 @@ def _repack(app_finder, l10n_finder, copier, formatter, non_chrome=set()):
             if not path:
                 continue
         else:
-            base = mozpath.basedir(p, paths.keys())
+            base = mozpath.basedir(p, list(paths.keys()))
             if base:
                 subpath = mozpath.relpath(p, base)
                 path = mozpath.normpath(mozpath.join(paths[base],
@@ -184,7 +183,7 @@ def _repack(app_finder, l10n_finder, copier, formatter, non_chrome=set()):
 
     # Add localized manifest entries from the langpack.
     l10n_manifests = []
-    for base in set(e.base for e in l10n.entries):
+    for base in {e.base for e in l10n.entries}:
         m = ManifestFile(base, [e for e in l10n.entries if e.base == base])
         path = mozpath.join(base, 'chrome.%s.manifest' % l10n_locale)
         l10n_manifests.append((path, m))
@@ -207,7 +206,7 @@ def _repack(app_finder, l10n_finder, copier, formatter, non_chrome=set()):
                     formatter.add(p, f)
 
     # Transplant jar preloading information.
-    for path, log in app_finder.jarlogs.iteritems():
+    for path, log in app_finder.jarlogs.items():
         assert isinstance(copier[path], Jarrer)
         copier[path].preload([l.replace(locale, l10n_locale) for l in log])
 
@@ -238,7 +237,7 @@ def repack(source, l10n, extra_l10n={}, non_resources=[], non_chrome=set()):
         finders = {
             '': l10n_finder,
         }
-        for base, path in extra_l10n.iteritems():
+        for base, path in extra_l10n.items():
             finders[base] = UnpackFinder(path)
         l10n_finder = ComposedFinder(finders)
     copier = FileCopier()
diff --git a/python/mozbuild/mozpack/packager/unpack.py b/python/mozbuild/mozpack/packager/unpack.py
index 515705c0d7..b28a3fc20a 100644
--- a/python/mozbuild/mozpack/packager/unpack.py
+++ b/python/mozbuild/mozpack/packager/unpack.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import mozpack.path as mozpath
 from mozpack.files import (
@@ -27,7 +26,7 @@ from mozpack.packager.formats import (
     FlatFormatter,
     STARTUP_CACHE_PATHS,
 )
-from urlparse import urlparse
+from urllib.parse import urlparse
 
 
 class UnpackFinder(BaseFinder):
@@ -148,7 +147,7 @@ class UnpackFinder(BaseFinder):
             self.optimizedjars = True
         self.compressed = max(self.compressed, jar.compression)
         if jar.last_preloaded:
-            jarlog = jar.entries.keys()
+            jarlog = list(jar.entries.keys())
             self.jarlogs[path] = jarlog[:jarlog.index(jar.last_preloaded) + 1]
         return jar
 
diff --git a/python/mozbuild/mozpack/path.py b/python/mozbuild/mozpack/path.py
index 7ea8ea85ad..239c226dce 100644
--- a/python/mozbuild/mozpack/path.py
+++ b/python/mozbuild/mozpack/path.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import posixpath
 import os
diff --git a/python/mozbuild/mozpack/test/support/minify_js_verify.py b/python/mozbuild/mozpack/test/support/minify_js_verify.py
index 8e4e8b7590..d4cffb7b3b 100644
--- a/python/mozbuild/mozpack/test/support/minify_js_verify.py
+++ b/python/mozbuild/mozpack/test/support/minify_js_verify.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import print_function
 import sys
 
 
diff --git a/python/mozbuild/mozpack/test/test_archive.py b/python/mozbuild/mozpack/test/test_archive.py
index 6f61f7eb7a..3bad0f56b8 100644
--- a/python/mozbuild/mozpack/test/test_archive.py
+++ b/python/mozbuild/mozpack/test/test_archive.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import hashlib
 import os
@@ -69,7 +68,7 @@ class TestArchive(unittest.TestCase):
         try:
             tp = os.path.join(d, 'test.tar')
             with open(tp, 'wb') as fh:
-                with self.assertRaisesRegexp(ValueError, 'not a regular'):
+                with self.assertRaisesRegex(ValueError, 'not a regular'):
                     create_tar_from_files(fh, {'test': d})
         finally:
             shutil.rmtree(d)
@@ -89,9 +88,9 @@ class TestArchive(unittest.TestCase):
 
             tp = os.path.join(d, 'test.tar')
             with open(tp, 'wb') as fh:
-                with self.assertRaisesRegexp(ValueError, 'cannot add file with setuid'):
+                with self.assertRaisesRegex(ValueError, 'cannot add file with setuid'):
                     create_tar_from_files(fh, {'test': uid})
-                with self.assertRaisesRegexp(ValueError, 'cannot add file with setuid'):
+                with self.assertRaisesRegex(ValueError, 'cannot add file with setuid'):
                     create_tar_from_files(fh, {'test': gid})
         finally:
             shutil.rmtree(d)
diff --git a/python/mozbuild/mozpack/test/test_chrome_manifest.py b/python/mozbuild/mozpack/test/test_chrome_manifest.py
index 690c6acdc9..1ffeba7237 100644
--- a/python/mozbuild/mozpack/test/test_chrome_manifest.py
+++ b/python/mozbuild/mozpack/test/test_chrome_manifest.py
@@ -24,7 +24,7 @@ from mozpack.chrome.manifest import (
     parse_manifest_line,
 )
 from mozpack.errors import errors, AccumulatedErrors
-from test_errors import TestErrors
+from .test_errors import TestErrors
 
 
 class TestManifest(unittest.TestCase):
@@ -91,7 +91,7 @@ class TestManifest(unittest.TestCase):
         with mozunit.MockedOpen({'manifest': '\n'.join(manifest),
                                  'other/manifest': '\n'.join(other_manifest)}):
             # Ensure we have tests for all types of manifests.
-            self.assertEqual(set(type(e) for e in expected_result),
+            self.assertEqual({type(e) for e in expected_result},
                              set(MANIFESTS_TYPES.values()))
             self.assertEqual(list(parse_manifest(os.curdir, 'manifest')),
                              expected_result)
diff --git a/python/mozbuild/mozpack/test/test_copier.py b/python/mozbuild/mozpack/test/test_copier.py
index 6688b3d5ef..06fa34a4d8 100644
--- a/python/mozbuild/mozpack/test/test_copier.py
+++ b/python/mozbuild/mozpack/test/test_copier.py
@@ -127,7 +127,7 @@ class TestFileRegistry(BaseTestFileRegistry, unittest.TestCase):
             'bar': [],
         }
         reg = FileRegistry()
-        for path, parts in cases.iteritems():
+        for path, parts in cases.items():
             self.assertEqual(reg._partial_paths(path), parts)
 
     def test_file_registry(self):
@@ -212,10 +212,10 @@ class TestFileCopier(TestWithTmpDir):
         result = copier.copy(self.tmpdir)
         self.assertEqual(self.all_files(self.tmpdir), set(copier.paths()))
         self.assertEqual(self.all_dirs(self.tmpdir),
-                         set(['foo/deep/nested/directory', 'qux']))
+                         {'foo/deep/nested/directory', 'qux'})
 
-        self.assertEqual(result.updated_files, set(self.tmppath(p) for p in
-            self.all_files(self.tmpdir)))
+        self.assertEqual(result.updated_files, {self.tmppath(p) for p in
+            self.all_files(self.tmpdir)})
         self.assertEqual(result.existing_files, set())
         self.assertEqual(result.removed_files, set())
         self.assertEqual(result.removed_directories, set())
@@ -224,9 +224,9 @@ class TestFileCopier(TestWithTmpDir):
         copier.add('test', GeneratedFile('test'))
         result = copier.copy(self.tmpdir)
         self.assertEqual(self.all_files(self.tmpdir), set(copier.paths()))
-        self.assertEqual(self.all_dirs(self.tmpdir), set(['qux']))
-        self.assertEqual(result.removed_files, set(self.tmppath(p) for p in
-            ('foo/bar', 'foo/qux', 'foo/deep/nested/directory/file')))
+        self.assertEqual(self.all_dirs(self.tmpdir), {'qux'})
+        self.assertEqual(result.removed_files, {self.tmppath(p) for p in
+            ('foo/bar', 'foo/qux', 'foo/deep/nested/directory/file')})
 
     def test_symlink_directory_replaced(self):
         """Directory symlinks in destination are replaced if they need to be
@@ -289,7 +289,7 @@ class TestFileCopier(TestWithTmpDir):
         self.assertFalse(stat.S_ISDIR(st.st_mode))
 
         self.assertEqual(self.all_files(dest), set(copier.paths()))
-        self.assertEqual(self.all_dirs(dest), set(['foo/bar']))
+        self.assertEqual(self.all_dirs(dest), {'foo/bar'})
 
         self.assertEqual(result.removed_directories, set())
         self.assertEqual(len(result.updated_files), 1)
@@ -304,11 +304,11 @@ class TestFileCopier(TestWithTmpDir):
         self.assertFalse(stat.S_ISLNK(st.st_mode))
         self.assertTrue(stat.S_ISDIR(st.st_mode))
 
-        self.assertEqual(result.removed_files, set([link]))
+        self.assertEqual(result.removed_files, {link})
         self.assertEqual(result.removed_directories, set())
 
         self.assertEqual(self.all_files(dest), set(copier.paths()))
-        self.assertEqual(self.all_dirs(dest), set(['foo/bar', 'zot']))
+        self.assertEqual(self.all_dirs(dest), {'foo/bar', 'zot'})
 
         # If remove_unaccounted and remove_empty_directories, then
         # both the symlink and its containing directory are removed.
@@ -319,11 +319,11 @@ class TestFileCopier(TestWithTmpDir):
             remove_empty_directories=True,
             remove_all_directory_symlinks=False)
 
-        self.assertEqual(result.removed_files, set([link]))
-        self.assertEqual(result.removed_directories, set([self.tmppath('dest/zot')]))
+        self.assertEqual(result.removed_files, {link})
+        self.assertEqual(result.removed_directories, {self.tmppath('dest/zot')})
 
         self.assertEqual(self.all_files(dest), set(copier.paths()))
-        self.assertEqual(self.all_dirs(dest), set(['foo/bar']))
+        self.assertEqual(self.all_dirs(dest), {'foo/bar'})
 
     def test_permissions(self):
         """Ensure files without write permission can be deleted."""
@@ -362,12 +362,12 @@ class TestFileCopier(TestWithTmpDir):
 
         result = copier.copy(self.tmpdir, remove_unaccounted=False)
 
-        self.assertEqual(self.all_files(self.tmpdir), set(['foo', 'bar',
-            'populateddir/foo']))
-        self.assertEqual(self.all_dirs(self.tmpdir), set(['populateddir']))
+        self.assertEqual(self.all_files(self.tmpdir), {'foo', 'bar',
+            'populateddir/foo'})
+        self.assertEqual(self.all_dirs(self.tmpdir), {'populateddir'})
         self.assertEqual(result.removed_files, set())
         self.assertEqual(result.removed_directories,
-            set([self.tmppath('emptydir')]))
+            {self.tmppath('emptydir')})
 
     def test_no_remove_empty_directories(self):
         copier = FileCopier()
@@ -386,10 +386,10 @@ class TestFileCopier(TestWithTmpDir):
         result = copier.copy(self.tmpdir, remove_unaccounted=False,
             remove_empty_directories=False)
 
-        self.assertEqual(self.all_files(self.tmpdir), set(['foo', 'bar',
-            'populateddir/foo']))
-        self.assertEqual(self.all_dirs(self.tmpdir), set(['emptydir',
-            'populateddir']))
+        self.assertEqual(self.all_files(self.tmpdir), {'foo', 'bar',
+            'populateddir/foo'})
+        self.assertEqual(self.all_dirs(self.tmpdir), {'emptydir',
+            'populateddir'})
         self.assertEqual(result.removed_files, set())
         self.assertEqual(result.removed_directories, set())
 
@@ -414,7 +414,7 @@ class TestFileCopier(TestWithTmpDir):
         self.assertTrue(stat.S_ISDIR(st.st_mode))
 
         # What's worse, we have no record that dest was created.
-        self.assertEquals(len(result.updated_files), 0)
+        self.assertEqual(len(result.updated_files), 0)
 
         # But we do have an erroneous record of an optional file
         # existing when it does not.
diff --git a/python/mozbuild/mozpack/test/test_errors.py b/python/mozbuild/mozpack/test/test_errors.py
index 16e2b04964..ecd0e1b808 100644
--- a/python/mozbuild/mozpack/test/test_errors.py
+++ b/python/mozbuild/mozpack/test/test_errors.py
@@ -13,7 +13,7 @@ import sys
 from cStringIO import StringIO
 
 
-class TestErrors(object):
+class TestErrors:
     def setUp(self):
         errors.out = StringIO()
         errors.ignore_errors(False)
@@ -30,14 +30,14 @@ class TestErrorsImpl(TestErrors, unittest.TestCase):
         errors.warn('foo')
         self.assertRaises(ErrorMessage, errors.error, 'foo')
         self.assertRaises(ErrorMessage, errors.fatal, 'foo')
-        self.assertEquals(self.get_output(), ['Warning: foo'])
+        self.assertEqual(self.get_output(), ['Warning: foo'])
 
     def test_ignore_errors(self):
         errors.ignore_errors()
         errors.warn('foo')
         errors.error('bar')
         self.assertRaises(ErrorMessage, errors.fatal, 'foo')
-        self.assertEquals(self.get_output(), ['Warning: foo', 'Warning: bar'])
+        self.assertEqual(self.get_output(), ['Warning: foo', 'Warning: bar'])
 
     def test_no_error(self):
         with errors.accumulate():
@@ -47,14 +47,14 @@ class TestErrorsImpl(TestErrors, unittest.TestCase):
         with self.assertRaises(AccumulatedErrors):
             with errors.accumulate():
                 errors.error('1')
-        self.assertEquals(self.get_output(), ['Error: 1'])
+        self.assertEqual(self.get_output(), ['Error: 1'])
 
     def test_error_loop(self):
         with self.assertRaises(AccumulatedErrors):
             with errors.accumulate():
                 for i in range(3):
                     errors.error('%d' % i)
-        self.assertEquals(self.get_output(),
+        self.assertEqual(self.get_output(),
                           ['Error: 0', 'Error: 1', 'Error: 2'])
 
     def test_multiple_errors(self):
@@ -67,7 +67,7 @@ class TestErrorsImpl(TestErrors, unittest.TestCase):
                     else:
                         errors.error('%d' % i)
                 errors.error('bar')
-        self.assertEquals(self.get_output(),
+        self.assertEqual(self.get_output(),
                           ['Error: foo', 'Error: 0', 'Error: 1',
                            'Warning: 2', 'Error: bar'])
 
diff --git a/python/mozbuild/mozpack/test/test_files.py b/python/mozbuild/mozpack/test/test_files.py
index 6fd6178288..260a458805 100644
--- a/python/mozbuild/mozpack/test/test_files.py
+++ b/python/mozbuild/mozpack/test/test_files.py
@@ -81,7 +81,7 @@ class TestWithTmpDir(unittest.TestCase):
         try:
             os.symlink(dummy_path, self.tmppath('dummy_symlink'))
             os.remove(self.tmppath('dummy_symlink'))
-        except EnvironmentError:
+        except OSError:
             pass
         finally:
             os.remove(dummy_path)
@@ -146,7 +146,7 @@ class TestDest(TestWithTmpDir):
         dest.write('qux')
         self.assertEqual(dest.read(), 'qux')
 
-rand = ''.join(random.choice(string.letters) for i in xrange(131597))
+rand = ''.join(random.choice(string.letters) for i in range(131597))
 samples = [
     '',
     'test',
@@ -268,12 +268,12 @@ class TestAbsoluteSymlinkFile(TestWithTmpDir):
     def test_absolute_relative(self):
         AbsoluteSymlinkFile('/foo')
 
-        with self.assertRaisesRegexp(ValueError, 'Symlink target not absolute'):
+        with self.assertRaisesRegex(ValueError, 'Symlink target not absolute'):
             AbsoluteSymlinkFile('./foo')
 
     def test_symlink_file(self):
         source = self.tmppath('test_path')
-        with open(source, 'wt') as fh:
+        with open(source, 'w') as fh:
             fh.write('Hello world')
 
         s = AbsoluteSymlinkFile(source)
@@ -293,7 +293,7 @@ class TestAbsoluteSymlinkFile(TestWithTmpDir):
         # If symlinks are supported, an existing file should be replaced by a
         # symlink.
         source = self.tmppath('test_path')
-        with open(source, 'wt') as fh:
+        with open(source, 'w') as fh:
             fh.write('source')
 
         dest = self.tmppath('dest')
@@ -477,7 +477,7 @@ class TestPreprocessedFile(TestWithTmpDir):
 
 class TestExistingFile(TestWithTmpDir):
     def test_required_missing_dest(self):
-        with self.assertRaisesRegexp(ErrorMessage, 'Required existing file'):
+        with self.assertRaisesRegex(ErrorMessage, 'Required existing file'):
             f = ExistingFile(required=True)
             f.copy(self.tmppath('dest'))
 
@@ -566,7 +566,7 @@ class TestDeflatedFile(TestWithTmpDir):
         with JarWriter(src) as jar:
             for content in samples:
                 name = ''.join(random.choice(string.letters)
-                               for i in xrange(8))
+                               for i in range(8))
                 jar.add(name, content, compress=True)
                 contents[name] = content
 
@@ -718,7 +718,7 @@ foo2_xpt = GeneratedFile(
 
 
 def read_interfaces(file):
-    return dict((i.name, i) for i in Typelib.read(file).interfaces)
+    return {i.name: i for i in Typelib.read(file).interfaces}
 
 
 class TestXPTFile(TestWithTmpDir):
@@ -830,7 +830,7 @@ class TestMinifiedJavaScript(TestWithTmpDir):
         self.assertEqual(mini_lines, orig_f.open().readlines())
 
 
-class MatchTestTemplate(object):
+class MatchTestTemplate:
     def prepare_match_test(self, with_dotfiles=False):
         self.add('bar')
         self.add('foo/bar')
@@ -1072,7 +1072,7 @@ class TestComposedFinder(MatchTestTemplate, TestWithTmpDir):
 @unittest.skipUnless(hglib, 'hglib not available')
 class TestMercurialRevisionFinder(MatchTestTemplate, TestWithTmpDir):
     def setUp(self):
-        super(TestMercurialRevisionFinder, self).setUp()
+        super().setUp()
         hglib.init(self.tmpdir)
 
     def add(self, path):
diff --git a/python/mozbuild/mozpack/test/test_manifests.py b/python/mozbuild/mozpack/test/test_manifests.py
index 7d926a0c8a..3171e04f4b 100644
--- a/python/mozbuild/mozpack/test/test_manifests.py
+++ b/python/mozbuild/mozpack/test/test_manifests.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 import os
 
@@ -187,13 +186,13 @@ class TestInstallManifest(TestWithTmpDir):
         with open(to_delete, 'a'):
             pass
 
-        with open(self.tmppath('s_source'), 'wt') as fh:
+        with open(self.tmppath('s_source'), 'w') as fh:
             fh.write('symlink!')
 
-        with open(self.tmppath('c_source'), 'wt') as fh:
+        with open(self.tmppath('c_source'), 'w') as fh:
             fh.write('copy!')
 
-        with open(self.tmppath('p_source'), 'wt') as fh:
+        with open(self.tmppath('p_source'), 'w') as fh:
             fh.write('#define FOO 1\npreprocess!')
 
         with open(self.tmppath('dest/e_dest'), 'a'):
@@ -215,19 +214,19 @@ class TestInstallManifest(TestWithTmpDir):
         self.assertTrue(os.path.exists(self.tmppath('dest/content')))
         self.assertFalse(os.path.exists(to_delete))
 
-        with open(self.tmppath('dest/s_dest'), 'rt') as fh:
+        with open(self.tmppath('dest/s_dest')) as fh:
             self.assertEqual(fh.read(), 'symlink!')
 
-        with open(self.tmppath('dest/c_dest'), 'rt') as fh:
+        with open(self.tmppath('dest/c_dest')) as fh:
             self.assertEqual(fh.read(), 'copy!')
 
-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+        with open(self.tmppath('dest/p_dest')) as fh:
             self.assertEqual(fh.read(), 'preprocess!')
 
-        self.assertEqual(result.updated_files, set(self.tmppath(p) for p in (
-            'dest/s_dest', 'dest/c_dest', 'dest/p_dest', 'dest/content')))
+        self.assertEqual(result.updated_files, {self.tmppath(p) for p in (
+            'dest/s_dest', 'dest/c_dest', 'dest/p_dest', 'dest/content')})
         self.assertEqual(result.existing_files,
-            set([self.tmppath('dest/e_dest'), self.tmppath('dest/o_dest')]))
+            {self.tmppath('dest/e_dest'), self.tmppath('dest/o_dest')})
         self.assertEqual(result.removed_files, {to_delete})
         self.assertEqual(result.removed_directories, set())
 
@@ -237,12 +236,12 @@ class TestInstallManifest(TestWithTmpDir):
         dest = self.tmppath('dest')
         include = self.tmppath('p_incl')
 
-        with open(include, 'wt') as fh:
+        with open(include, 'w') as fh:
             fh.write('#define INCL\n')
         time = os.path.getmtime(include) - 3
         os.utime(include, (time, time))
 
-        with open(self.tmppath('p_source'), 'wt') as fh:
+        with open(self.tmppath('p_source'), 'w') as fh:
             fh.write('#ifdef FOO\n#if BAZ == QUX\nPASS1\n#endif\n#endif\n')
             fh.write('#ifdef DEPTEST\nPASS2\n#endif\n')
             fh.write('#include p_incl\n#ifdef INCLTEST\nPASS3\n#endif\n')
@@ -262,7 +261,7 @@ class TestInstallManifest(TestWithTmpDir):
 
         self.assertTrue(os.path.exists(self.tmppath('dest/p_dest')))
 
-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+        with open(self.tmppath('dest/p_dest')) as fh:
             self.assertEqual(fh.read(), 'PASS1\n')
 
         # Create a second manifest with the preprocessed file, then apply it.
@@ -290,7 +289,7 @@ class TestInstallManifest(TestWithTmpDir):
         m2.populate_registry(c)
         self.assertTrue(c.copy(dest))
 
-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+        with open(self.tmppath('dest/p_dest')) as fh:
             self.assertEqual(fh.read(), 'PASS2\n')
 
         # Set the time on the manifest back, so it won't be picked up as
@@ -300,7 +299,7 @@ class TestInstallManifest(TestWithTmpDir):
 
         # Update the contents of a file included by the source file. This should
         # cause the destination to be regenerated.
-        with open(include, 'wt') as fh:
+        with open(include, 'w') as fh:
             fh.write('#define INCLTEST\n')
 
         time = os.path.getmtime(include) - 1
@@ -309,7 +308,7 @@ class TestInstallManifest(TestWithTmpDir):
         m2.populate_registry(c)
         self.assertTrue(c.copy(dest))
 
-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+        with open(self.tmppath('dest/p_dest')) as fh:
             self.assertEqual(fh.read(), 'PASS2\nPASS3\n')
 
     def test_preprocessor_dependencies(self):
@@ -321,12 +320,12 @@ class TestInstallManifest(TestWithTmpDir):
         include = self.tmppath('p_incl')
         os.mkdir(dest)
 
-        with open(source, 'wt') as fh:
+        with open(source, 'w') as fh:
             fh.write('#define SRC\nSOURCE\n')
         time = os.path.getmtime(source) - 3
         os.utime(source, (time, time))
 
-        with open(include, 'wt') as fh:
+        with open(include, 'w') as fh:
             fh.write('INCLUDE\n')
         time = os.path.getmtime(source) - 3
         os.utime(include, (time, time))
@@ -346,11 +345,11 @@ class TestInstallManifest(TestWithTmpDir):
         m.populate_registry(c)
         self.assertTrue(c.copy(dest))
 
-        with open(destfile, 'rt') as fh:
+        with open(destfile) as fh:
             self.assertEqual(fh.read(), 'SOURCE\n')
 
         # Next, modify the source to #INCLUDE another file.
-        with open(source, 'wt') as fh:
+        with open(source, 'w') as fh:
             fh.write('SOURCE\n#include p_incl\n')
         time = os.path.getmtime(source) - 1
         os.utime(destfile, (time, time))
@@ -362,7 +361,7 @@ class TestInstallManifest(TestWithTmpDir):
         m.populate_registry(c)
         c.copy(dest)
 
-        with open(destfile, 'rt') as fh:
+        with open(destfile) as fh:
             self.assertEqual(fh.read(), 'SOURCE\nINCLUDE\n')
 
         # Set the time on the source file back, so it won't be picked up as
@@ -371,7 +370,7 @@ class TestInstallManifest(TestWithTmpDir):
         os.utime(source, (time, time))
 
         # Now, modify the include file (but not the original source).
-        with open(include, 'wt') as fh:
+        with open(include, 'w') as fh:
             fh.write('INCLUDE MODIFIED\n')
         time = os.path.getmtime(include) - 1
         os.utime(destfile, (time, time))
@@ -383,7 +382,7 @@ class TestInstallManifest(TestWithTmpDir):
         m.populate_registry(c)
         c.copy(dest)
 
-        with open(destfile, 'rt') as fh:
+        with open(destfile) as fh:
             self.assertEqual(fh.read(), 'SOURCE\nINCLUDE MODIFIED\n')
 
         # ORing an InstallManifest should copy file dependencies
diff --git a/python/mozbuild/mozpack/test/test_mozjar.py b/python/mozbuild/mozpack/test/test_mozjar.py
index 9484030069..063bdfc244 100644
--- a/python/mozbuild/mozpack/test/test_mozjar.py
+++ b/python/mozbuild/mozpack/test/test_mozjar.py
@@ -17,7 +17,7 @@ from mozpack.test.test_files import MockDest
 import unittest
 import mozunit
 from cStringIO import StringIO
-from urllib import pathname2url
+from urllib.request import pathname2url
 import mozpack.path as mozpath
 import os
 
@@ -310,12 +310,12 @@ class TestJarLog(unittest.TestCase):
             mozpath.normsep(os.path.normcase(os.path.realpath(p)))
         baz_jar = canonicalize('bar/baz.jar')
         qux_zip = canonicalize('qux.zip')
-        self.assertEqual(set(log.keys()), set([
+        self.assertEqual(set(log.keys()), {
             baz_jar,
             (qux_zip, 'omni.ja'),
             (qux_zip, 'baz/baz.jar', 'omni.ja'),
             (qux_zip, 'baz/baz.jar', 'foo.zip', 'omni.ja'),
-        ]))
+        })
         self.assertEqual(log[baz_jar], [
             'first',
             'second',
diff --git a/python/mozbuild/mozpack/test/test_packager.py b/python/mozbuild/mozpack/test/test_packager.py
index 397f405386..97db960154 100644
--- a/python/mozbuild/mozpack/test/test_packager.py
+++ b/python/mozbuild/mozpack/test/test_packager.py
@@ -54,7 +54,7 @@ class TestPreprocessManifest(unittest.TestCase):
     ]
 
     def setUp(self):
-        class MockSink(object):
+        class MockSink:
             def __init__(self):
                 self.log = []
 
@@ -92,7 +92,7 @@ class TestPreprocessManifest(unittest.TestCase):
                          [((self.MANIFEST_PATH, 12), 'add', 'baz', 'baz.exe')])
 
 
-class MockFinder(object):
+class MockFinder:
     def __init__(self, files):
         self.files = files
         self.log = []
@@ -107,7 +107,7 @@ class MockFinder(object):
         return self.find('')
 
 
-class MockFormatter(object):
+class MockFormatter:
     def __init__(self):
         self.log = []
 
@@ -300,10 +300,10 @@ class TestSimplePackager(unittest.TestCase):
         ])
 
         self.assertEqual(packager.get_bases(),
-                         set(['', 'addon', 'addon2', 'addon3', 'addon4',
+                         {'', 'addon', 'addon2', 'addon3', 'addon4',
                               'addon5', 'addon6', 'addon7', 'addon8',
-                              'addon9', 'addon10', 'addon11', 'qux']))
-        self.assertEqual(packager.get_bases(addons=False), set(['', 'qux']))
+                              'addon9', 'addon10', 'addon11', 'qux'})
+        self.assertEqual(packager.get_bases(addons=False), {'', 'qux'})
 
     def test_simple_packager_manifest_consistency(self):
         formatter = MockFormatter()
@@ -408,7 +408,7 @@ class TestSimpleManifestSink(unittest.TestCase):
 
 class TestCallDeque(unittest.TestCase):
     def test_call_deque(self):
-        class Logger(object):
+        class Logger:
             def __init__(self):
                 self._log = []
 
diff --git a/python/mozbuild/mozpack/test/test_packager_formats.py b/python/mozbuild/mozpack/test/test_packager_formats.py
index 4ba61e880f..06f7c5942b 100644
--- a/python/mozbuild/mozpack/test/test_packager_formats.py
+++ b/python/mozbuild/mozpack/test/test_packager_formats.py
@@ -120,7 +120,7 @@ for addon in ('addon0', 'addon1'):
             'chrome/chrome.manifest': [
                 'content content foo/bar/',
             ],
-            'chrome/foo/bar/baz': FILES[mozpath.join(addon, 'chrome/foo/bar/baz')],
+            'chrome/foo/bar/baz': FILES[mozpath.join(addon, 'chrome/foo/bar/baz'.items()],
             'components/components.manifest': [
                 'interfaces interfaces.xpt',
             ],
@@ -128,7 +128,7 @@ for addon in ('addon0', 'addon1'):
                 'foo': read_interfaces(foo2_xpt.open())['foo'],
                 'bar': read_interfaces(bar_xpt.open())['bar'],
             },
-        }.iteritems()
+        })
     })
 
 RESULT_JAR = {
@@ -174,7 +174,7 @@ RESULT_JAR.update({
     },
     'addon1.xpi': {
         mozpath.relpath(p, 'addon1'): f
-        for p, f in RESULT_FLAT.iteritems()
+        for p, f in RESULT_FLAT.items()
         if p.startswith('addon1/')
     },
 })
@@ -234,7 +234,7 @@ RESULT_OMNIJAR['omni.foo'].update({
 CONTENTS_WITH_BASE = {
     'bases': {
         mozpath.join('base/root', b) if b else 'base/root': a
-        for b, a in CONTENTS['bases'].iteritems()
+        for b, a in CONTENTS['bases'].items()
     },
     'manifests': [
         m.move(mozpath.join('base/root', m.base))
@@ -242,7 +242,7 @@ CONTENTS_WITH_BASE = {
     ],
     'files': {
         mozpath.join('base/root', p): f
-        for p, f in CONTENTS['files'].iteritems()
+        for p, f in CONTENTS['files'].items()
     },
 }
 
@@ -255,7 +255,7 @@ CONTENTS_WITH_BASE['files'].update(EXTRA_CONTENTS)
 def result_with_base(results):
     result = {
         mozpath.join('base/root', p): v
-        for p, v in results.iteritems()
+        for p, v in results.items()
     }
     result.update(EXTRA_CONTENTS)
     return result
@@ -277,7 +277,7 @@ def fill_formatter(formatter, contents):
     for manifest in contents['manifests']:
         formatter.add_manifest(manifest)
 
-    for k, v in contents['files'].iteritems():
+    for k, v in contents['files'].items():
         if k.endswith('.xpt'):
             formatter.add_interfaces(k, v)
         else:
diff --git a/python/mozbuild/mozpack/test/test_packager_l10n.py b/python/mozbuild/mozpack/test/test_packager_l10n.py
index c797eadd17..17d95ec893 100644
--- a/python/mozbuild/mozpack/test/test_packager_l10n.py
+++ b/python/mozbuild/mozpack/test/test_packager_l10n.py
@@ -4,7 +4,7 @@
 
 import unittest
 import mozunit
-from test_packager import MockFinder
+from .test_packager import MockFinder
 from mozpack.packager import l10n
 from mozpack.files import (
     GeneratedFile,
@@ -117,8 +117,8 @@ class TestL10NRepack(unittest.TestCase):
         }
 
         self.assertEqual(
-            dict((p, f.open().read()) for p, f in copier),
-            dict((p, f.open().read()) for p, f in repacked.iteritems())
+            {p: f.open().read() for p, f in copier},
+            {p: f.open().read() for p, f in repacked.items()}
         )
 
 
diff --git a/python/mozbuild/mozpack/test/test_packager_unpack.py b/python/mozbuild/mozpack/test/test_packager_unpack.py
index d201cabf74..913cf63c30 100644
--- a/python/mozbuild/mozpack/test/test_packager_unpack.py
+++ b/python/mozbuild/mozpack/test/test_packager_unpack.py
@@ -56,7 +56,7 @@ class TestUnpack(TestWithTmpDir):
     def test_omnijar_unpack(self):
         class OmniFooFormatter(OmniJarFormatter):
             def __init__(self, registry):
-                super(OmniFooFormatter, self).__init__(registry, 'omni.foo')
+                super().__init__(registry, 'omni.foo')
 
         self._unpack_test(OmniFooFormatter)
 
diff --git a/python/mozbuild/mozpack/test/test_unify.py b/python/mozbuild/mozpack/test/test_unify.py
index a2bbb44702..52f3f46b42 100644
--- a/python/mozbuild/mozpack/test/test_unify.py
+++ b/python/mozbuild/mozpack/test/test_unify.py
@@ -186,7 +186,7 @@ class TestUnifiedBuildFinder(TestUnified):
             # Now create the files from the above table and compare
             results = []
             for emid, (rdf_a, rdf_b, result) in enumerate(testcases):
-                filename = 'ext/id{0}/install.rdf'.format(emid)
+                filename = 'ext/id{}/install.rdf'.format(emid)
                 self.create_one('a', filename, rdf_a)
                 self.create_one('b', filename, rdf_b)
                 results.append((filename, result))
diff --git a/python/mozbuild/mozpack/unify.py b/python/mozbuild/mozpack/unify.py
index 3c8a8d6057..9dd63c4622 100644
--- a/python/mozbuild/mozpack/unify.py
+++ b/python/mozbuild/mozpack/unify.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 from mozpack.files import (
     BaseFinder,
@@ -73,7 +72,7 @@ class UnifiedExecutableFile(BaseFile):
         creating the instance.
         skip_if_older is ignored.
         '''
-        assert isinstance(dest, basestring)
+        assert isinstance(dest, str)
         tmpfiles = []
         try:
             for e in self._executables:
@@ -137,7 +136,7 @@ class UnifiedFinder(BaseFinder):
                 errors.error('File missing in %s: %s' %
                              (self._finder1.base, p))
         for p in [p for p in files1 if not p in files2]:
-            errors.error('File missing in %s: %s' % (self._finder2.base, p))
+            errors.error('File missing in {}: {}'.format(self._finder2.base, p))
 
     def _report_difference(self, path, file1, file2):
         '''
diff --git a/python/mozlint/mozlint/cli.py b/python/mozlint/mozlint/cli.py
index 2a35064ed4..55efda5b5e 100644
--- a/python/mozlint/mozlint/cli.py
+++ b/python/mozlint/mozlint/cli.py
@@ -2,8 +2,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import print_function, unicode_literals
 
+from __future__ import print_function
 import os
 import sys
 from argparse import ArgumentParser, REMAINDER
@@ -105,7 +105,7 @@ def run(paths, linters, fmt, rev, workdir, **lintargs):
     # Explicitly utf-8 encode the output as some of the formatters make
     # use of unicode characters. This will prevent a UnicodeEncodeError
     # on environments where utf-8 isn't the default
-    print(formatter(results).encode('utf-8', 'replace'))
+    print((formatter(results).encode('utf-8', 'replace')))
     return lint.return_code
 
 
diff --git a/python/mozlint/mozlint/formatters/__init__.py b/python/mozlint/mozlint/formatters/__init__.py
index 33aca0446d..2650c6e015 100644
--- a/python/mozlint/mozlint/formatters/__init__.py
+++ b/python/mozlint/mozlint/formatters/__init__.py
@@ -9,7 +9,7 @@ from .stylish import StylishFormatter
 from .treeherder import TreeherderFormatter
 
 
-class JSONFormatter(object):
+class JSONFormatter:
     def __call__(self, results):
         return json.dumps(results, cls=ResultEncoder)
 
diff --git a/python/mozlint/mozlint/formatters/stylish.py b/python/mozlint/mozlint/formatters/stylish.py
index 62ddfbeb6a..8ec942fae0 100644
--- a/python/mozlint/mozlint/formatters/stylish.py
+++ b/python/mozlint/mozlint/formatters/stylish.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 from ..result import ResultContainer
 
@@ -12,24 +11,24 @@ except ImportError:
     blessings = None
 
 
-class NullTerminal(object):
+class NullTerminal:
     """Replacement for `blessings.Terminal()` that does no formatting."""
-    class NullCallableString(unicode):
+    class NullCallableString(str):
         """A dummy callable Unicode stolen from blessings"""
         def __new__(cls):
-            new = unicode.__new__(cls, u'')
+            new = str.__new__(cls, '')
             return new
 
         def __call__(self, *args):
             if len(args) != 1 or isinstance(args[0], int):
-                return u''
+                return ''
             return args[0]
 
     def __getattr__(self, attr):
         return self.NullCallableString()
 
 
-class StylishFormatter(object):
+class StylishFormatter:
     """Formatter based on the eslint default."""
 
     # Colors later on in the list are fallbacks in case the terminal
@@ -82,7 +81,7 @@ class StylishFormatter(object):
 
         num_errors = 0
         num_warnings = 0
-        for path, errors in sorted(result.iteritems()):
+        for path, errors in sorted(result.items()):
             self._reset_max()
 
             message.append(self.term.underline(path))
diff --git a/python/mozlint/mozlint/formatters/treeherder.py b/python/mozlint/mozlint/formatters/treeherder.py
index 7c27011cf4..80b89ff286 100644
--- a/python/mozlint/mozlint/formatters/treeherder.py
+++ b/python/mozlint/mozlint/formatters/treeherder.py
@@ -2,12 +2,11 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 from ..result import ResultContainer
 
 
-class TreeherderFormatter(object):
+class TreeherderFormatter:
     """Formatter for treeherder friendly output.
 
     This formatter looks ugly, but prints output such that
@@ -18,7 +17,7 @@ class TreeherderFormatter(object):
 
     def __call__(self, result):
         message = []
-        for path, errors in sorted(result.iteritems()):
+        for path, errors in sorted(result.items()):
             for err in errors:
                 assert isinstance(err, ResultContainer)
 
diff --git a/python/mozlint/mozlint/parser.py b/python/mozlint/mozlint/parser.py
index f350d0de75..9d54d98e4c 100644
--- a/python/mozlint/mozlint/parser.py
+++ b/python/mozlint/mozlint/parser.py
@@ -11,7 +11,7 @@ from .types import supported_types
 from .errors import LinterNotFound, LinterParseError
 
 
-class Parser(object):
+class Parser:
     """Reads and validates `.lint` files."""
     required_attributes = (
         'name',
@@ -63,7 +63,7 @@ class Parser(object):
 
         for attr in ('include', 'exclude'):
             if attr in linter and (not isinstance(linter[attr], list) or
-                                   not all(isinstance(a, basestring) for a in linter[attr])):
+                                   not all(isinstance(a, str) for a in linter[attr])):
                 raise LinterParseError(linter['path'], "The {} directive must be a "
                                                        "list of strings!".format(attr))
 
diff --git a/python/mozlint/mozlint/pathutils.py b/python/mozlint/mozlint/pathutils.py
index 532904dca7..cf79d58150 100644
--- a/python/mozlint/mozlint/pathutils.py
+++ b/python/mozlint/mozlint/pathutils.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 import os
 
@@ -10,7 +9,7 @@ from mozpack import path as mozpath
 from mozpack.files import FileFinder
 
 
-class FilterPath(object):
+class FilterPath:
     """Helper class to make comparing and matching file paths easier."""
     def __init__(self, path, exclude=None):
         self.path = os.path.normpath(path)
@@ -86,8 +85,8 @@ def filterpaths(paths, linter, **lintargs):
             path = os.path.join(root, path)
         return FilterPath(path)
 
-    include = map(normalize, include)
-    exclude = map(normalize, exclude)
+    include = list(map(normalize, include))
+    exclude = list(map(normalize, exclude))
 
     # Paths with and without globs will be handled separately,
     # pull them apart now.
diff --git a/python/mozlint/mozlint/result.py b/python/mozlint/mozlint/result.py
index 0c56f1d761..490b2eefc5 100644
--- a/python/mozlint/mozlint/result.py
+++ b/python/mozlint/mozlint/result.py
@@ -5,7 +5,7 @@
 from json import dumps, JSONEncoder
 
 
-class ResultContainer(object):
+class ResultContainer:
     """Represents a single lint error and its related metadata.
 
     :param linter: name of the linter that flagged this error
diff --git a/python/mozlint/mozlint/roller.py b/python/mozlint/mozlint/roller.py
index 2d1608dd87..6cb00da7d5 100644
--- a/python/mozlint/mozlint/roller.py
+++ b/python/mozlint/mozlint/roller.py
@@ -2,14 +2,13 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 import os
 import signal
 import sys
 import traceback
 from collections import defaultdict
-from Queue import Empty
+from queue import Empty
 from multiprocessing import (
     Manager,
     Pool,
@@ -35,7 +34,7 @@ def _run_linters(queue, paths, **lintargs):
             # also received SIGINT. By the time the worker gets back here, the
             # Queue is dead and IOError is raised.
             linter_path = queue.get(False)
-        except (Empty, IOError):
+        except (Empty, OSError):
             return results, return_code
 
         # Ideally we would pass the entire LINTER definition as an argument
@@ -67,7 +66,7 @@ def _run_worker(*args, **lintargs):
         sys.stdout.flush()
 
 
-class LintRoller(object):
+class LintRoller:
     """Registers and runs linters.
 
     :param root: Path to which relative paths will be joined. If
@@ -91,7 +90,7 @@ class LintRoller(object):
 
         :param paths: A path or iterable of paths to linter definitions.
         """
-        if isinstance(paths, basestring):
+        if isinstance(paths, str):
             paths = (paths,)
 
         for path in paths:
@@ -108,7 +107,7 @@ class LintRoller(object):
                  :class:`~result.ResultContainer`s as the value.
         """
         paths = paths or []
-        if isinstance(paths, basestring):
+        if isinstance(paths, str):
             paths = [paths]
 
         if not self.linters:
@@ -120,7 +119,7 @@ class LintRoller(object):
         if workdir:
             paths.extend(self.vcs.by_workdir())
         paths = paths or ['.']
-        paths = map(os.path.abspath, paths)
+        paths = list(map(os.path.abspath, paths))
 
         # Set up multiprocessing
         m = Manager()
@@ -149,6 +148,6 @@ class LintRoller(object):
             results, return_code = worker.get()
             if results or return_code:
                 self.return_code = 1
-            for k, v in results.iteritems():
+            for k, v in results.items():
                 all_results[k].extend(v)
         return all_results
diff --git a/python/mozlint/mozlint/types.py b/python/mozlint/mozlint/types.py
index 2f49ae2bf2..064b5d595e 100644
--- a/python/mozlint/mozlint/types.py
+++ b/python/mozlint/mozlint/types.py
@@ -2,8 +2,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
+from __future__ import print_function
 import re
 import sys
 from abc import ABCMeta, abstractmethod
@@ -13,11 +13,11 @@ from mozlog.reader import LogHandler
 
 from . import result
 from .pathutils import filterpaths
+import six
 
 
-class BaseType(object):
+class BaseType(six.with_metaclass(ABCMeta)):
     """Abstract base class for all types of linters."""
-    __metaclass__ = ABCMeta
     batch = False
 
     def __call__(self, paths, linter, **lintargs):
@@ -31,7 +31,7 @@ class BaseType(object):
         """
         paths = filterpaths(paths, linter, **lintargs)
         if not paths:
-            print("{}: no files to lint in specified paths".format(linter['name']))
+            print(("{}: no files to lint in specified paths".format(linter['name'])))
             return
 
         if self.batch:
@@ -52,13 +52,12 @@ class BaseType(object):
         pass
 
 
-class LineType(BaseType):
+class LineType(six.with_metaclass(ABCMeta, BaseType)):
     """Abstract base class for linter types that check each line individually.
 
     Subclasses of this linter type will read each file and check the provided
     payload against each line one by one.
     """
-    __metaclass__ = ABCMeta
 
     @abstractmethod
     def condition(payload, line):
@@ -67,7 +66,7 @@ class LineType(BaseType):
     def _lint(self, path, linter, **lintargs):
         payload = linter['payload']
 
-        with open(path, 'r') as fh:
+        with open(path) as fh:
             lines = fh.readlines()
 
         errors = []
diff --git a/python/mozlint/mozlint/vcs.py b/python/mozlint/mozlint/vcs.py
index 6a118f2e6a..b7d02e4c3d 100644
--- a/python/mozlint/mozlint/vcs.py
+++ b/python/mozlint/mozlint/vcs.py
@@ -6,7 +6,7 @@ import os
 import subprocess
 
 
-class VCSFiles(object):
+class VCSFiles:
     def __init__(self):
         self._root = None
         self._vcs = None
diff --git a/python/mozlint/test/test_formatters.py b/python/mozlint/test/test_formatters.py
index b9e6512b24..e1ecdba0e7 100644
--- a/python/mozlint/test/test_formatters.py
+++ b/python/mozlint/test/test_formatters.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 import json
 import sys
diff --git a/python/mozlint/test/test_roller.py b/python/mozlint/test/test_roller.py
index b4b82c346c..207b935022 100644
--- a/python/mozlint/test/test_roller.py
+++ b/python/mozlint/test/test_roller.py
@@ -29,7 +29,7 @@ def test_roll_successful(lint, linters, files):
     assert len(result) == 1
     assert lint.return_code == 1
 
-    path = result.keys()[0]
+    path = list(result.keys())[0]
     assert os.path.basename(path) == 'foobar.js'
 
     errors = result[path]
diff --git a/python/mozversioncontrol/mozversioncontrol/__init__.py b/python/mozversioncontrol/mozversioncontrol/__init__.py
index 211d42ef14..e69a9db0bf 100644
--- a/python/mozversioncontrol/mozversioncontrol/__init__.py
+++ b/python/mozversioncontrol/mozversioncontrol/__init__.py
@@ -2,14 +2,33 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this,
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import, print_function, unicode_literals
 
+from __future__ import print_function
 import os
 import re
 import subprocess
 import which
 
-from distutils.version import LooseVersion
+class LooseVersion:
+    """Simple version comparison (replacement for distutils.version.LooseVersion)."""
+    def __init__(self, vstring):
+        self.vstring = vstring
+        self.version = [int(x) if x.isdigit() else x for x in re.split(r'[.\-]', vstring)]
+    def __str__(self): return self.vstring
+    def __repr__(self): return "LooseVersion('%s')" % self.vstring
+    def _cmp(self, other):
+        if not isinstance(other, LooseVersion):
+            other = LooseVersion(str(other))
+        try:
+            if self.version == other.version: return 0
+            if self.version < other.version: return -1
+            return 1
+        except TypeError: return -1
+    def __lt__(self, o): return self._cmp(o) < 0
+    def __le__(self, o): return self._cmp(o) <= 0
+    def __eq__(self, o): return self._cmp(o) == 0
+    def __ge__(self, o): return self._cmp(o) >= 0
+    def __gt__(self, o): return self._cmp(o) > 0
 
 def get_tool_path(tool):
     """Obtain the path of `tool`."""
@@ -30,7 +49,7 @@ def get_tool_path(tool):
                     '|mach bootstrap| to ensure your environment is up to ' +
                     'date.' % tool)
 
-class Repository(object):
+class Repository:
     '''A class wrapping utility methods around version control repositories.'''
     def __init__(self, path, tool):
         self.path = os.path.abspath(path)
@@ -49,7 +68,7 @@ class Repository(object):
         if self._version:
             return self._version
         info = self._run('--version').strip()
-        match = re.search('version ([^\+\)]+)', info)
+        match = re.search(r'version ([^\+\)]+)', info)
         if not match:
             raise Exception('Unable to identify tool version.')
 
@@ -74,7 +93,7 @@ class Repository(object):
 class HgRepository(Repository):
     '''An implementation of `Repository` for Mercurial repositories.'''
     def __init__(self, path):
-        super(HgRepository, self).__init__(path, 'hg')
+        super().__init__(path, 'hg')
         self._env[b'HGPLAIN'] = b'1'
 
     def get_modified_files(self):
@@ -95,11 +114,11 @@ class HgRepository(Repository):
 class GitRepository(Repository):
     '''An implementation of `Repository` for Git repositories.'''
     def __init__(self, path):
-        super(GitRepository, self).__init__(path, 'git')
+        super().__init__(path, 'git')
 
     def get_modified_files(self):
         # This is a little wonky, but it's good enough for this purpose.
-        return [bits[1] for bits in map(lambda line: line.strip().split(), self._run('status', '--porcelain').splitlines()) if 'M' in bits[0]]
+        return [bits[1] for bits in [line.strip().split() for line in self._run('status', '--porcelain').splitlines()] if 'M' in bits[0]]
 
     def add_remove_files(self, path):
         self._run('add', path)
diff --git a/python/mozversioncontrol/mozversioncontrol/repoupdate.py b/python/mozversioncontrol/mozversioncontrol/repoupdate.py
index 08be73a344..291889cfa9 100644
--- a/python/mozversioncontrol/mozversioncontrol/repoupdate.py
+++ b/python/mozversioncontrol/mozversioncontrol/repoupdate.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this,
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 import os
 import subprocess
@@ -19,7 +18,7 @@ def update_mercurial_repo(hg, repo, path, revision='default',
         args.extend(global_args)
 
     for host, fingerprint in sorted(hostfingerprints.items()):
-        args.extend(['--config', 'hostfingerprints.%s=%s' % (host,
+        args.extend(['--config', 'hostfingerprints.{}={}'.format(host,
             fingerprint)])
 
     if os.path.exists(path):
diff --git a/python/psutil/docs/conf.py b/python/psutil/docs/conf.py
index ad880110f8..bc906b3948 100644
--- a/python/psutil/docs/conf.py
+++ b/python/psutil/docs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 # psutil documentation build configuration file, created by
 # sphinx-quickstart.
@@ -24,7 +23,7 @@ HERE = os.path.abspath(os.path.dirname(__file__))
 
 def get_version():
     INIT = os.path.abspath(os.path.join(HERE, '../psutil/__init__.py'))
-    with open(INIT, 'r') as f:
+    with open(INIT) as f:
         for line in f:
             if line.startswith('__version__'):
                 ret = eval(line.strip().split(' = ')[1])
@@ -63,7 +62,7 @@ master_doc = 'index'
 
 # General information about the project.
 project = PROJECT_NAME
-copyright = '2009-%s, %s' % (THIS_YEAR, AUTHOR)
+copyright = '2009-{}, {}'.format(THIS_YEAR, AUTHOR)
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
diff --git a/python/psutil/examples/disk_usage.py b/python/psutil/examples/disk_usage.py
index d8600a8c47..bf3fa231f6 100755
--- a/python/psutil/examples/disk_usage.py
+++ b/python/psutil/examples/disk_usage.py
@@ -15,6 +15,7 @@ Device               Total     Used     Free  Use %      Type  Mount
 /dev/sda2           600.0M   312.4M   287.6M    52%   fuseblk  /media/Recovery
 """
 
+from __future__ import print_function
 import sys
 import os
 import psutil
@@ -33,14 +34,14 @@ def bytes2human(n):
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = float(n) / prefix[s]
-            return '%.1f%s' % (value, s)
+            return '{:.1f}{}'.format(value, s)
     return "%sB" % n
 
 
 def main():
     templ = "%-17s %8s %8s %8s %5s%% %9s  %s"
-    print(templ % ("Device", "Total", "Used", "Free", "Use ", "Type",
-                   "Mount"))
+    print((templ % ("Device", "Total", "Used", "Free", "Use ", "Type",
+                   "Mount")))
     for part in psutil.disk_partitions(all=False):
         if os.name == 'nt':
             if 'cdrom' in part.opts or part.fstype == '':
@@ -49,14 +50,14 @@ def main():
                 # partition or just hang.
                 continue
         usage = psutil.disk_usage(part.mountpoint)
-        print(templ % (
+        print((templ % (
             part.device,
             bytes2human(usage.total),
             bytes2human(usage.used),
             bytes2human(usage.free),
             int(usage.percent),
             part.fstype,
-            part.mountpoint))
+            part.mountpoint)))
 
 if __name__ == '__main__':
     sys.exit(main())
diff --git a/python/psutil/examples/free.py b/python/psutil/examples/free.py
index 913ca58a4c..1687e5c3e7 100755
--- a/python/psutil/examples/free.py
+++ b/python/psutil/examples/free.py
@@ -13,6 +13,7 @@ Mem:      10125520    8625996    1499524          0     349500    3307836
 Swap:            0          0          0
 """
 
+from __future__ import print_function
 import psutil
 
 
@@ -20,22 +21,22 @@ def main():
     virt = psutil.virtual_memory()
     swap = psutil.swap_memory()
     templ = "%-7s %10s %10s %10s %10s %10s %10s"
-    print(templ % ('', 'total', 'used', 'free', 'shared', 'buffers', 'cache'))
-    print(templ % (
+    print((templ % ('', 'total', 'used', 'free', 'shared', 'buffers', 'cache')))
+    print((templ % (
         'Mem:',
         int(virt.total / 1024),
         int(virt.used / 1024),
         int(virt.free / 1024),
         int(getattr(virt, 'shared', 0) / 1024),
         int(getattr(virt, 'buffers', 0) / 1024),
-        int(getattr(virt, 'cached', 0) / 1024)))
-    print(templ % (
+        int(getattr(virt, 'cached', 0) / 1024))))
+    print((templ % (
         'Swap:', int(swap.total / 1024),
         int(swap.used / 1024),
         int(swap.free / 1024),
         '',
         '',
-        ''))
+        '')))
 
 if __name__ == '__main__':
     main()
diff --git a/python/psutil/examples/ifconfig.py b/python/psutil/examples/ifconfig.py
index e7a436cc0a..8ac04527a2 100644
--- a/python/psutil/examples/ifconfig.py
+++ b/python/psutil/examples/ifconfig.py
@@ -36,7 +36,6 @@ eth0 (speed=100MB, duplex=full, mtu=1500, up=yes):
              broadcast : ff:ff:ff:ff:ff:ff
 """
 
-from __future__ import print_function
 import socket
 
 import psutil
@@ -59,7 +58,7 @@ def main():
     stats = psutil.net_if_stats()
     for nic, addrs in psutil.net_if_addrs().items():
         if nic in stats:
-            print("%s (speed=%sMB, duplex=%s, mtu=%s, up=%s):" % (
+            print("{} (speed={}MB, duplex={}, mtu={}, up={}):".format(
                 nic, stats[nic].speed, duplex_map[stats[nic].duplex],
                 stats[nic].mtu, "yes" if stats[nic].isup else "no"))
         else:
diff --git a/python/psutil/examples/iotop.py b/python/psutil/examples/iotop.py
index 16ac7fbf61..d273d45862 100755
--- a/python/psutil/examples/iotop.py
+++ b/python/psutil/examples/iotop.py
@@ -86,7 +86,7 @@ def bytes2human(n):
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = float(n) / prefix[s]
-            return '%.2f %s/s' % (value, s)
+            return '{:.2f} {}/s'.format(value, s)
     return '%.2f B/s' % (n)
 
 
diff --git a/python/psutil/examples/meminfo.py b/python/psutil/examples/meminfo.py
index c463a3de4b..d314a5eea1 100755
--- a/python/psutil/examples/meminfo.py
+++ b/python/psutil/examples/meminfo.py
@@ -30,6 +30,7 @@ Sin        :      0B
 Sout       :      0B
 """
 
+from __future__ import print_function
 import psutil
 
 
@@ -46,7 +47,7 @@ def bytes2human(n):
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = float(n) / prefix[s]
-            return '%.1f%s' % (value, s)
+            return '{:.1f}{}'.format(value, s)
     return "%sB" % n
 
 
@@ -55,7 +56,7 @@ def pprint_ntuple(nt):
         value = getattr(nt, name)
         if name != 'percent':
             value = bytes2human(value)
-        print('%-10s : %7s' % (name.capitalize(), value))
+        print(('%-10s : %7s' % (name.capitalize(), value)))
 
 
 def main():
diff --git a/python/psutil/examples/netstat.py b/python/psutil/examples/netstat.py
index 884622e9e3..af7c224d8e 100755
--- a/python/psutil/examples/netstat.py
+++ b/python/psutil/examples/netstat.py
@@ -19,6 +19,7 @@ tcp   172.17.42.1:55797  127.0.0.1:443    CLOSE_WAIT    13651  GoogleTalkPlugi
 ...
 """
 
+from __future__ import print_function
 import socket
 from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
 
@@ -37,9 +38,9 @@ proto_map = {
 
 def main():
     templ = "%-5s %-30s %-30s %-13s %-6s %s"
-    print(templ % (
+    print((templ % (
         "Proto", "Local address", "Remote address", "Status", "PID",
-        "Program name"))
+        "Program name")))
     proc_names = {}
     for p in psutil.process_iter():
         try:
@@ -51,14 +52,14 @@ def main():
         raddr = ""
         if c.raddr:
             raddr = "%s:%s" % (c.raddr)
-        print(templ % (
+        print((templ % (
             proto_map[(c.family, c.type)],
             laddr,
             raddr or AD,
             c.status,
             c.pid or AD,
             proc_names.get(c.pid, '?')[:15],
-        ))
+        )))
 
 if __name__ == '__main__':
     main()
diff --git a/python/psutil/examples/nettop.py b/python/psutil/examples/nettop.py
index 7a8343ee4c..6b4fc60db2 100755
--- a/python/psutil/examples/nettop.py
+++ b/python/psutil/examples/nettop.py
@@ -87,7 +87,7 @@ def bytes2human(n):
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = float(n) / prefix[s]
-            return '%.2f %s' % (value, s)
+            return '{:.2f} {}'.format(value, s)
     return '%.2f B' % (n)
 
 
diff --git a/python/psutil/examples/pidof.py b/python/psutil/examples/pidof.py
index 8692a3152b..f740c4da43 100755
--- a/python/psutil/examples/pidof.py
+++ b/python/psutil/examples/pidof.py
@@ -47,7 +47,7 @@ def main():
         pgname = sys.argv[1]
     pids = pidof(pgname)
     if pids:
-        print(" ".join(pids))
+        print((" ".join(pids)))
 
 if __name__ == '__main__':
     main()
diff --git a/python/psutil/examples/pmap.py b/python/psutil/examples/pmap.py
index 7593777aef..3525a2859a 100755
--- a/python/psutil/examples/pmap.py
+++ b/python/psutil/examples/pmap.py
@@ -30,6 +30,7 @@ ffffffffff600000         0K  r-xp    [vsyscall]
 ...
 """
 
+from __future__ import print_function
 import sys
 
 import psutil
@@ -39,19 +40,19 @@ def main():
     if len(sys.argv) != 2:
         sys.exit('usage: pmap ')
     p = psutil.Process(int(sys.argv[1]))
-    print("pid=%s, name=%s" % (p.pid, p.name()))
+    print(("pid={}, name={}".format(p.pid, p.name())))
     templ = "%-16s %10s  %-7s %s"
-    print(templ % ("Address", "RSS", "Mode", "Mapping"))
+    print((templ % ("Address", "RSS", "Mode", "Mapping")))
     total_rss = 0
     for m in p.memory_maps(grouped=False):
         total_rss += m.rss
-        print(templ % (
+        print((templ % (
             m.addr.split('-')[0].zfill(16),
             str(m.rss / 1024) + 'K',
             m.perms,
-            m.path))
-    print("-" * 33)
-    print(templ % ("Total", str(total_rss / 1024) + 'K', '', ''))
+            m.path)))
+    print(("-" * 33))
+    print((templ % ("Total", str(total_rss / 1024) + 'K', '', '')))
 
 if __name__ == '__main__':
     main()
diff --git a/python/psutil/examples/process_detail.py b/python/psutil/examples/process_detail.py
index e20371aefe..5f6539e595 100755
--- a/python/psutil/examples/process_detail.py
+++ b/python/psutil/examples/process_detail.py
@@ -49,7 +49,7 @@ def convert_bytes(n):
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = float(n) / prefix[s]
-            return '%.1f%s' % (value, s)
+            return '{:.1f}{}'.format(value, s)
     return "%sB" % n
 
 
@@ -86,7 +86,7 @@ def run(pid):
         started = ACCESS_DENIED
     io = pinfo.get('io_counters', ACCESS_DENIED)
     if pinfo['memory_info'] != ACCESS_DENIED:
-        mem = '%s%% (resident=%s, virtual=%s) ' % (
+        mem = '{}% (resident={}, virtual={}) '.format(
             round(pinfo['memory_percent'], 1),
             convert_bytes(pinfo['memory_info'].rss),
             convert_bytes(pinfo['memory_info'].vms))
@@ -97,7 +97,7 @@ def run(pid):
     print_('pid', pinfo['pid'])
     print_('name', pinfo['name'])
     print_('exe', pinfo['exe'])
-    print_('parent', '%s %s' % (pinfo['ppid'], parent))
+    print_('parent', '{} {}'.format(pinfo['ppid'], parent))
     print_('cmdline', ' '.join(pinfo['cmdline']))
     print_('started', started)
     print_('user', pinfo['username'])
@@ -109,7 +109,7 @@ def run(pid):
         print_('terminal', pinfo['terminal'] or '')
     print_('cwd', pinfo['cwd'])
     print_('memory', mem)
-    print_('cpu', '%s%% (user=%s, system=%s)' % (
+    print_('cpu', '{}% (user={}, system={})'.format(
         pinfo['cpu_percent'],
         getattr(pinfo['cpu_times'], 'user', '?'),
         getattr(pinfo['cpu_times'], 'system', '?')))
@@ -117,23 +117,23 @@ def run(pid):
     print_('niceness', pinfo['nice'])
     print_('num threads', pinfo['num_threads'])
     if io != ACCESS_DENIED:
-        print_('I/O', 'bytes-read=%s, bytes-written=%s' % (
+        print_('I/O', 'bytes-read={}, bytes-written={}'.format(
             convert_bytes(io.read_bytes),
             convert_bytes(io.write_bytes)))
     if children:
         print_('children', '')
         for child in children:
-            print_('', 'pid=%s name=%s' % (child.pid, child.name()))
+            print_('', 'pid={} name={}'.format(child.pid, child.name()))
 
     if pinfo['open_files'] != ACCESS_DENIED:
         print_('open files', '')
         for file in pinfo['open_files']:
-            print_('', 'fd=%s %s ' % (file.fd, file.path))
+            print_('', 'fd={} {} '.format(file.fd, file.path))
 
     if pinfo['threads']:
         print_('running threads', '')
         for thread in pinfo['threads']:
-            print_('', 'id=%s, user-time=%s, sys-time=%s' % (
+            print_('', 'id={}, user-time={}, sys-time={}'.format(
                 thread.id, thread.user_time, thread.system_time))
     if pinfo['connections'] not in (ACCESS_DENIED, []):
         print_('open connections', '')
@@ -149,7 +149,7 @@ def run(pid):
                 rip, rport = '*', '*'
             else:
                 rip, rport = conn.raddr
-            print_('', '%s:%s -> %s:%s type=%s status=%s' % (
+            print_('', '{}:{} -> {}:{} type={} status={}'.format(
                 lip, lport, rip, rport, type, conn.status))
 
 
diff --git a/python/psutil/examples/ps.py b/python/psutil/examples/ps.py
index 2b67bd18ff..5ad82c1d2a 100644
--- a/python/psutil/examples/ps.py
+++ b/python/psutil/examples/ps.py
@@ -11,6 +11,7 @@ $ python examples/ps.py
 ...
 """
 
+from __future__ import print_function
 import datetime
 import os
 import time
@@ -26,8 +27,8 @@ def main():
     if os.name == 'posix':
         attrs.append('uids')
         attrs.append('terminal')
-    print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
-                   "START", "TIME", "COMMAND"))
+    print((templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
+                   "START", "TIME", "COMMAND")))
     for p in psutil.process_iter():
         try:
             pinfo = p.as_dict(attrs, ad_value='')
@@ -64,7 +65,7 @@ def main():
                 int(pinfo['memory_info'].rss / 1024) or '?'
             memp = pinfo['memory_percent'] and \
                 round(pinfo['memory_percent'], 1) or '?'
-            print(templ % (
+            print((templ % (
                 user[:10],
                 pinfo['pid'],
                 pinfo['cpu_percent'],
@@ -74,7 +75,7 @@ def main():
                 pinfo.get('terminal', '') or '?',
                 ctime,
                 cputime,
-                pinfo['name'].strip() or '?'))
+                pinfo['name'].strip() or '?')))
 
 
 if __name__ == '__main__':
diff --git a/python/psutil/examples/pstree.py b/python/psutil/examples/pstree.py
index 1bf8c9c049..3fd69b4236 100644
--- a/python/psutil/examples/pstree.py
+++ b/python/psutil/examples/pstree.py
@@ -40,7 +40,7 @@ def print_tree(parent, tree, indent=''):
         name = psutil.Process(parent).name()
     except psutil.Error:
         name = "?"
-    print(parent, name)
+    print((parent, name))
     if parent not in tree:
         return
     children = tree[parent][:-1]
diff --git a/python/psutil/examples/top.py b/python/psutil/examples/top.py
index 30df417f55..62aaf37436 100755
--- a/python/psutil/examples/top.py
+++ b/python/psutil/examples/top.py
@@ -92,7 +92,7 @@ def bytes2human(n):
     for s in reversed(symbols):
         if n >= prefix[s]:
             value = int(float(n) / prefix[s])
-            return '%s%s' % (value, s)
+            return '{}{}'.format(value, s)
     return "%sB" % n
 
 
@@ -125,7 +125,7 @@ def print_header(procs_status, num_procs):
     """Print system-related info, above the process list."""
 
     def get_dashes(perc):
-        dashes = "|" * int((float(perc) / 10 * 4))
+        dashes = "|" * int(float(perc) / 10 * 4)
         empty_dashes = " " * (40 - len(dashes))
         return dashes, empty_dashes
 
@@ -161,9 +161,9 @@ def print_header(procs_status, num_procs):
     st = []
     for x, y in procs_status.items():
         if y:
-            st.append("%s=%s" % (x, y))
+            st.append("{}={}".format(x, y))
     st.sort(key=lambda x: x[:3] in ('run', 'sle'), reverse=1)
-    print_line(" Processes: %s (%s)" % (num_procs, ' '.join(st)))
+    print_line(" Processes: {} ({})".format(num_procs, ' '.join(st)))
     # load average, uptime
     uptime = datetime.utcnow() - datetime.fromtimestamp(psutil.boot_time())
     av1, av2, av3 = os.getloadavg()
@@ -187,8 +187,8 @@ def refresh_window(procs, procs_status):
         # is expressed as: "mm:ss.ms"
         if p.dict['cpu_times'] is not None:
             ctime = timedelta(seconds=sum(p.dict['cpu_times']))
-            ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60,
-                                  str((ctime.seconds % 60)).zfill(2),
+            ctime = "{}:{}.{}".format(ctime.seconds // 60 % 60,
+                                  str(ctime.seconds % 60).zfill(2),
                                   str(ctime.microseconds)[:2])
         else:
             ctime = ''
diff --git a/python/psutil/examples/who.py b/python/psutil/examples/who.py
index b382bebfa3..1d8aa2854e 100755
--- a/python/psutil/examples/who.py
+++ b/python/psutil/examples/who.py
@@ -15,6 +15,7 @@ giampaolo       pts/8           2014-02-24 18:25  (:0)
 giampaolo       pts/9           2014-02-27 01:32  (:0)
 """
 
+from __future__ import print_function
 from datetime import datetime
 
 import psutil
@@ -23,11 +24,11 @@ import psutil
 def main():
     users = psutil.users()
     for user in users:
-        print("%-15s %-15s %s  (%s)" % (
+        print(("%-15s %-15s %s  (%s)" % (
             user.name,
             user.terminal or '-',
             datetime.fromtimestamp(user.started).strftime("%Y-%m-%d %H:%M"),
-            user.host))
+            user.host)))
 
 if __name__ == '__main__':
     main()
diff --git a/python/psutil/psutil/__init__.py b/python/psutil/psutil/__init__.py
index 1444425b8d..b39aa31bac 100644
--- a/python/psutil/psutil/__init__.py
+++ b/python/psutil/psutil/__init__.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
@@ -10,8 +9,8 @@ running processes and system utilization (CPU, memory, disks, network)
 in Python.
 """
 
-from __future__ import division
 
+from __future__ import print_function
 import collections
 import errno
 import functools
@@ -27,7 +26,7 @@ except ImportError:
 
 from . import _common
 from ._common import memoize
-from ._compat import callable, long
+from ._compat import callable, int
 from ._compat import PY3 as _PY3
 
 from ._common import (STATUS_RUNNING,  # NOQA
@@ -194,7 +193,7 @@ class Error(Exception):
         self.msg = msg
 
     def __repr__(self):
-        ret = "%s.%s %s" % (self.__class__.__module__,
+        ret = "{}.{} {}".format(self.__class__.__module__,
                             self.__class__.__name__, self.msg)
         return ret.strip()
 
@@ -213,7 +212,7 @@ class NoSuchProcess(Error):
         self.msg = msg
         if msg is None:
             if name:
-                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
+                details = "(pid={}, name={})".format(self.pid, repr(self.name))
             else:
                 details = "(pid=%s)" % self.pid
             self.msg = "process no longer exists " + details
@@ -235,10 +234,10 @@ class ZombieProcess(NoSuchProcess):
         self.msg = msg
         if msg is None:
             if name and ppid:
-                details = "(pid=%s, name=%s, ppid=%s)" % (
+                details = "(pid={}, name={}, ppid={})".format(
                     self.pid, repr(self.name), self.ppid)
             elif name:
-                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
+                details = "(pid={}, name={})".format(self.pid, repr(self.name))
             else:
                 details = "(pid=%s)" % self.pid
             self.msg = "process still exists but it's a zombie " + details
@@ -254,7 +253,7 @@ class AccessDenied(Error):
         self.msg = msg
         if msg is None:
             if (pid is not None) and (name is not None):
-                self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
+                self.msg = "(pid={}, name={})".format(pid, repr(name))
             elif (pid is not None):
                 self.msg = "(pid=%s)" % self.pid
             else:
@@ -272,7 +271,7 @@ class TimeoutExpired(Error):
         self.pid = pid
         self.name = name
         if (pid is not None) and (name is not None):
-            self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
+            self.msg += " (pid={}, name={})".format(pid, repr(name))
         elif (pid is not None):
             self.msg += " (pid=%s)" % self.pid
 
@@ -301,7 +300,7 @@ def _assert_pid_not_reused(fun):
     return wrapper
 
 
-class Process(object):
+class Process:
     """Represents an OS process with the given PID.
     If PID is omitted current process PID (os.getpid()) is used.
     Raise NoSuchProcess if PID does not exist.
@@ -341,7 +340,7 @@ class Process(object):
         if pid is None:
             pid = os.getpid()
         else:
-            if not _PY3 and not isinstance(pid, (int, long)):
+            if not _PY3 and not isinstance(pid, int):
                 raise TypeError('pid must be an integer (got %r)' % pid)
             if pid < 0:
                 raise ValueError('pid must be a positive integer (got %s)'
@@ -395,12 +394,12 @@ class Process(object):
         except AccessDenied:
             details = "(pid=%s)" % (self.pid)
         else:
-            details = "(pid=%s, name=%s)" % (pid, name)
-        return "%s.%s%s" % (self.__class__.__module__,
+            details = "(pid={}, name={})".format(pid, name)
+        return "{}.{}{}".format(self.__class__.__module__,
                             self.__class__.__name__, details)
 
     def __repr__(self):
-        return "<%s at %s>" % (self.__str__(), id(self))
+        return "<{} at {}>".format(self.__str__(), id(self))
 
     def __eq__(self, other):
         # Test for equality with another Process object based
@@ -432,9 +431,9 @@ class Process(object):
         AccessDenied or ZombieProcess exception is raised when
         retrieving that particular process information.
         """
-        excluded_names = set(
-            ['send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
-             'is_running', 'as_dict', 'parent', 'children', 'rlimit'])
+        excluded_names = {
+            'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
+             'is_running', 'as_dict', 'parent', 'children', 'rlimit'}
         retdict = dict()
         ls = set(attrs or [x for x in dir(self)])
         for name in ls:
@@ -972,7 +971,7 @@ class Process(object):
                 path = tupl[2]
                 nums = tupl[3:]
                 try:
-                    d[path] = map(lambda x, y: x + y, d[path], nums)
+                    d[path] = list(map(lambda x, y: x + y, d[path], nums))
                 except KeyError:
                     d[path] = nums
             nt = _psplatform.pmmap_grouped
@@ -1165,7 +1164,7 @@ class Popen(Process):
     def wait(self, timeout=None):
         if self.__subproc.returncode is not None:
             return self.__subproc.returncode
-        ret = super(Popen, self).wait(timeout)
+        ret = super().wait(timeout)
         self.__subproc.returncode = ret
         return ret
 
@@ -1678,7 +1677,7 @@ def disk_io_counters(perdisk=False):
             rawdict[disk] = _common.sdiskio(*fields)
         return rawdict
     else:
-        return _common.sdiskio(*[sum(x) for x in zip(*rawdict.values())])
+        return _common.sdiskio(*[sum(x) for x in zip(*list(rawdict.values()))])
 
 
 # =====================================================================
@@ -1713,7 +1712,7 @@ def net_io_counters(pernic=False):
             rawdict[nic] = _common.snetio(*fields)
         return rawdict
     else:
-        return _common.snetio(*[sum(x) for x in zip(*rawdict.values())])
+        return _common.snetio(*[sum(x) for x in zip(*list(rawdict.values()))])
 
 
 def net_connections(kind='inet'):
@@ -1836,8 +1835,8 @@ def test():
     if _POSIX:
         attrs.append('uids')
         attrs.append('terminal')
-    print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
-                   "START", "TIME", "COMMAND"))
+    print((templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
+                   "START", "TIME", "COMMAND")))
     for p in process_iter():
         try:
             pinfo = p.as_dict(attrs, ad_value='')
@@ -1866,7 +1865,7 @@ def test():
                 int(pinfo['memory_info'].rss / 1024) or '?'
             memp = pinfo['memory_percent'] and \
                 round(pinfo['memory_percent'], 1) or '?'
-            print(templ % (
+            print((templ % (
                 user[:10],
                 pinfo['pid'],
                 pinfo['cpu_percent'],
@@ -1876,12 +1875,9 @@ def test():
                 pinfo.get('terminal', '') or '?',
                 ctime,
                 cputime,
-                pinfo['name'].strip() or '?'))
+                pinfo['name'].strip() or '?')))
 
 
 del memoize, division
-if sys.version_info < (3, 0):
-    del num
-
 if __name__ == "__main__":
     test()
diff --git a/python/psutil/psutil/_common.py b/python/psutil/psutil/_common.py
index e9acf595d7..b338a0ba27 100644
--- a/python/psutil/psutil/_common.py
+++ b/python/psutil/psutil/_common.py
@@ -6,7 +6,6 @@
 
 """Common objects shared by all _ps* modules."""
 
-from __future__ import division
 import errno
 import functools
 import os
diff --git a/python/psutil/psutil/_compat.py b/python/psutil/psutil/_compat.py
index 38744a84ae..f7326834ce 100644
--- a/python/psutil/psutil/_compat.py
+++ b/python/psutil/psutil/_compat.py
@@ -17,17 +17,17 @@ PY3 = sys.version_info[0] == 3
 if PY3:
     long = int
     xrange = range
-    unicode = str
+    str = str
 
     def u(s):
         return s
 else:
-    long = long
+    long = int
     xrange = xrange
-    unicode = unicode
+    str = str
 
     def u(s):
-        return unicode(s, "unicode_escape")
+        return str(s, "unicode_escape")
 
 
 # removed in 3.0, reintroduced in 3.2
@@ -67,7 +67,7 @@ except ImportError:
 
     def _make_key(args, kwds, typed,
                   kwd_mark=(object(), ),
-                  fasttypes=set((int, str, frozenset, type(None))),
+                  fasttypes={int, str, frozenset, type(None)},
                   sorted=sorted, tuple=tuple, type=type, len=len):
         key = args
         if kwds:
diff --git a/python/psutil/psutil/_psbsd.py b/python/psutil/psutil/_psbsd.py
index db54a02e13..f2d3a4c6b7 100644
--- a/python/psutil/psutil/_psbsd.py
+++ b/python/psutil/psutil/_psbsd.py
@@ -84,7 +84,7 @@ def virtual_memory():
 
 def swap_memory():
     """System swap memory as (total, used, free, sin, sout) namedtuple."""
-    total, used, free, sin, sout = [x * PAGESIZE for x in cext.swap_mem()]
+    total, used, free, sin, sout = (x * PAGESIZE for x in cext.swap_mem())
     percent = usage_percent(used, total, _round=1)
     return _common.sswap(total, used, free, percent, sin, sout)
 
@@ -216,7 +216,7 @@ def net_connections(kind):
 
 def net_if_stats():
     """Get NIC stats (isup, duplex, speed, mtu)."""
-    names = net_io_counters().keys()
+    names = list(net_io_counters().keys())
     ret = {}
     for name in names:
         isup, duplex, speed, mtu = cext_posix.net_if_stats(name)
@@ -258,7 +258,7 @@ def wrap_exceptions(fun):
     return wrapper
 
 
-class Process(object):
+class Process:
     """Wrapper class around underlying C implementation."""
 
     __slots__ = ["pid", "_name", "_ppid"]
diff --git a/python/psutil/psutil/_pslinux.py b/python/psutil/psutil/_pslinux.py
index 7eb25f519c..f956ef44db 100644
--- a/python/psutil/psutil/_pslinux.py
+++ b/python/psutil/psutil/_pslinux.py
@@ -6,7 +6,6 @@
 
 """Linux platform implementation."""
 
-from __future__ import division
 
 import base64
 import errno
@@ -25,7 +24,8 @@ from . import _psutil_linux as cext
 from . import _psutil_posix as cext_posix
 from ._common import isfile_strict, usage_percent
 from ._common import NIC_DUPLEX_FULL, NIC_DUPLEX_HALF, NIC_DUPLEX_UNKNOWN
-from ._compat import PY3, long
+from ._compat import PY3, int
+import six
 
 if sys.version_info >= (3, 4):
     import enum
@@ -262,8 +262,8 @@ def cpu_count_logical():
         # https://github.com/giampaolo/psutil/issues/200
         # try to parse /proc/stat as a last resort
         if num == 0:
-            search = re.compile('cpu\d')
-            with open('/proc/stat', 'rt') as f:
+            search = re.compile(r'cpu\d')
+            with open('/proc/stat') as f:
                 for line in f:
                     line = line.split(' ')[0]
                     if search.match(line):
@@ -382,7 +382,7 @@ class Connections:
         inodes = defaultdict(list)
         for fd in os.listdir("/proc/%s/fd" % pid):
             try:
-                inode = os.readlink("/proc/%s/fd/%s" % (pid, fd))
+                inode = os.readlink("/proc/{}/fd/{}".format(pid, fd))
             except OSError as err:
                 # ENOENT == file which is gone in the meantime;
                 # os.stat('/proc/%s' % self.pid) will be done later
@@ -471,7 +471,7 @@ class Connections:
         if file.endswith('6') and not os.path.exists(file):
             # IPv6 not supported
             return
-        with open(file, 'rt') as f:
+        with open(file) as f:
             f.readline()  # skip the first line
             for line in f:
                 try:
@@ -479,7 +479,7 @@ class Connections:
                         line.split()[:10]
                 except ValueError:
                     raise RuntimeError(
-                        "error while parsing %s; malformed line %r" % (
+                        "error while parsing {}; malformed line {!r}".format(
                             file, line))
                 if inode in inodes:
                     # # We assume inet sockets are unique, so we error
@@ -504,7 +504,7 @@ class Connections:
 
     def process_unix(self, file, family, inodes, filter_pid=None):
         """Parse /proc/net/unix files."""
-        with open(file, 'rt') as f:
+        with open(file) as f:
             f.readline()  # skip the first line
             for line in f:
                 tokens = line.split()
@@ -512,7 +512,7 @@ class Connections:
                     _, _, _, _, type_, _, inode = tokens[0:7]
                 except ValueError:
                     raise RuntimeError(
-                        "error while parsing %s; malformed line %r" % (
+                        "error while parsing {}; malformed line {!r}".format(
                             file, line))
                 if inode in inodes:
                     # With UNIX sockets we can have a single inode
@@ -575,7 +575,7 @@ def net_io_counters():
     """Return network I/O statistics for every network interface
     installed on the system as a dict of raw tuples.
     """
-    with open("/proc/net/dev", "rt") as f:
+    with open("/proc/net/dev") as f:
         lines = f.readlines()
     retdict = {}
     for line in lines[2:]:
@@ -601,7 +601,7 @@ def net_if_stats():
     duplex_map = {cext.DUPLEX_FULL: NIC_DUPLEX_FULL,
                   cext.DUPLEX_HALF: NIC_DUPLEX_HALF,
                   cext.DUPLEX_UNKNOWN: NIC_DUPLEX_UNKNOWN}
-    names = net_io_counters().keys()
+    names = list(net_io_counters().keys())
     ret = {}
     for name in names:
         isup, duplex, speed, mtu = cext.net_if_stats(name)
@@ -626,7 +626,7 @@ def disk_io_counters():
 
     # determine partitions we want to look for
     partitions = []
-    with open("/proc/partitions", "rt") as f:
+    with open("/proc/partitions") as f:
         lines = f.readlines()[2:]
     for line in reversed(lines):
         _, _, _, name = line.split()
@@ -643,7 +643,7 @@ def disk_io_counters():
                 partitions.append(name)
     #
     retdict = {}
-    with open("/proc/diskstats", "rt") as f:
+    with open("/proc/diskstats") as f:
         lines = f.readlines()
     for line in lines:
         # http://www.mjmwired.net/kernel/Documentation/iostats.txt
@@ -669,7 +669,7 @@ def disk_io_counters():
 def disk_partitions(all=False):
     """Return mounted disk partitions as a list of namedtuples"""
     fstypes = set()
-    with open("/proc/filesystems", "r") as f:
+    with open("/proc/filesystems") as f:
         for line in f:
             line = line.strip()
             if not line.startswith("nodev"):
@@ -707,7 +707,7 @@ def wrap_exceptions(fun):
     def wrapper(self, *args, **kwargs):
         try:
             return fun(self, *args, **kwargs)
-        except EnvironmentError as err:
+        except OSError as err:
             # support for private module import
             if NoSuchProcess is None or AccessDenied is None:
                 raise
@@ -736,7 +736,7 @@ def wrap_exceptions_w_zombie(fun):
     return wrapper
 
 
-class Process(object):
+class Process:
     """Linux process implementation."""
 
     __slots__ = ["pid", "_name", "_ppid"]
@@ -887,7 +887,7 @@ class Process(object):
         #  ============================================================
         with open("/proc/%s/statm" % self.pid, "rb") as f:
             vms, rss, shared, text, lib, data, dirty = \
-                [int(x) * PAGESIZE for x in f.readline().split()[:7]]
+                (int(x) * PAGESIZE for x in f.readline().split()[:7])
         return pextmem(rss, vms, shared, text, lib, data, dirty)
 
     if os.path.exists('/proc/%s/smaps' % os.getpid()):
@@ -898,7 +898,7 @@ class Process(object):
             Fields are explained in 'man proc'; here is an updated (Apr 2012)
             version: http://goo.gl/fmebo
             """
-            with open("/proc/%s/smaps" % self.pid, "rt") as f:
+            with open("/proc/%s/smaps" % self.pid) as f:
                 first_line = f.readline()
                 current_block = [first_line]
 
@@ -996,11 +996,11 @@ class Process(object):
         retlist = []
         hit_enoent = False
         for thread_id in thread_ids:
-            fname = "/proc/%s/task/%s/stat" % (self.pid, thread_id)
+            fname = "/proc/{}/task/{}/stat".format(self.pid, thread_id)
             try:
                 with open(fname, 'rb') as f:
                     st = f.read().strip()
-            except IOError as err:
+            except OSError as err:
                 if err.errno == errno.ENOENT:
                     # no such file or directory; it means thread
                     # disappeared on us
@@ -1062,7 +1062,7 @@ class Process(object):
         @wrap_exceptions
         def ionice_set(self, ioclass, value):
             if value is not None:
-                if not PY3 and not isinstance(value, (int, long)):
+                if not PY3 and not isinstance(value, int):
                     msg = "value argument is not an integer (gor %r)" % value
                     raise TypeError(msg)
                 if not 0 <= value <= 8:
@@ -1138,7 +1138,7 @@ class Process(object):
         files = os.listdir("/proc/%s/fd" % self.pid)
         hit_enoent = False
         for fd in files:
-            file = "/proc/%s/fd/%s" % (self.pid, fd)
+            file = "/proc/{}/fd/{}".format(self.pid, fd)
             try:
                 file = os.readlink(file)
             except OSError as err:
diff --git a/python/psutil/psutil/_psosx.py b/python/psutil/psutil/_psosx.py
index 41875fe404..ef8b8f823e 100644
--- a/python/psutil/psutil/_psosx.py
+++ b/python/psutil/psutil/_psosx.py
@@ -170,7 +170,7 @@ def net_connections(kind='inet'):
 
 def net_if_stats():
     """Get NIC stats (isup, duplex, speed, mtu)."""
-    names = net_io_counters().keys()
+    names = list(net_io_counters().keys())
     ret = {}
     for name in names:
         isup, duplex, speed, mtu = cext_posix.net_if_stats(name)
@@ -212,7 +212,7 @@ def wrap_exceptions(fun):
     return wrapper
 
 
-class Process(object):
+class Process:
     """Wrapper class around underlying C implementation."""
 
     __slots__ = ["pid", "_name", "_ppid"]
diff --git a/python/psutil/psutil/_psposix.py b/python/psutil/psutil/_psposix.py
index 5bb16a386d..69bcf63595 100644
--- a/python/psutil/psutil/_psposix.py
+++ b/python/psutil/psutil/_psposix.py
@@ -13,7 +13,7 @@ import sys
 import time
 
 from ._common import sdiskusage, usage_percent, memoize
-from ._compat import PY3, unicode
+from ._compat import PY3, str
 
 
 class TimeoutExpired(Exception):
@@ -120,7 +120,7 @@ def disk_usage(path):
     try:
         st = os.statvfs(path)
     except UnicodeEncodeError:
-        if not PY3 and isinstance(path, unicode):
+        if not PY3 and isinstance(path, str):
             # this is a bug with os.statvfs() and unicode on
             # Python 2, see:
             # - https://github.com/giampaolo/psutil/issues/416
diff --git a/python/psutil/psutil/_pssunos.py b/python/psutil/psutil/_pssunos.py
index bc35a718c3..046ede4ca3 100644
--- a/python/psutil/psutil/_pssunos.py
+++ b/python/psutil/psutil/_pssunos.py
@@ -252,7 +252,7 @@ def wrap_exceptions(fun):
     def wrapper(self, *args, **kwargs):
         try:
             return fun(self, *args, **kwargs)
-        except EnvironmentError as err:
+        except OSError as err:
             # support for private module import
             if (NoSuchProcess is None or AccessDenied is None or
                     ZombieProcess is None):
@@ -271,7 +271,7 @@ def wrap_exceptions(fun):
     return wrapper
 
 
-class Process(object):
+class Process:
     """Wrapper class around underlying C implementation."""
 
     __slots__ = ["pid", "_name", "_ppid"]
@@ -317,7 +317,7 @@ class Process(object):
         # fine.
         try:
             return cext_posix.getpriority(self.pid)
-        except EnvironmentError as err:
+        except OSError as err:
             # 48 is 'operation not supported' but errno does not expose
             # it. It occurs for low system pids.
             if err.errno in (errno.ENOENT, errno.ESRCH, 48):
@@ -411,7 +411,7 @@ class Process(object):
             try:
                 utime, stime = cext.query_process_thread(
                     self.pid, tid)
-            except EnvironmentError as err:
+            except OSError as err:
                 # ENOENT == thread gone in meantime
                 if err.errno == errno.ENOENT:
                     hit_enoent = True
@@ -458,14 +458,14 @@ class Process(object):
                              stderr=subprocess.PIPE)
         stdout, stderr = p.communicate()
         if PY3:
-            stdout, stderr = [x.decode(sys.stdout.encoding)
-                              for x in (stdout, stderr)]
+            stdout, stderr = (x.decode(sys.stdout.encoding)
+                              for x in (stdout, stderr))
         if p.returncode != 0:
             if 'permission denied' in stderr.lower():
                 raise AccessDenied(self.pid, self._name)
             if 'no such process' in stderr.lower():
                 raise NoSuchProcess(self.pid, self._name)
-            raise RuntimeError("%r command error\n%s" % (cmd, stderr))
+            raise RuntimeError("{!r} command error\n{}".format(cmd, stderr))
 
         lines = stdout.split('\n')[2:]
         for i, line in enumerate(lines):
@@ -504,7 +504,7 @@ class Process(object):
     @wrap_exceptions
     def memory_maps(self):
         def toaddr(start, end):
-            return '%s-%s' % (hex(start)[2:].strip('L'),
+            return '{}-{}'.format(hex(start)[2:].strip('L'),
                               hex(end)[2:].strip('L'))
 
         retlist = []
@@ -515,7 +515,7 @@ class Process(object):
             addr = toaddr(addr, addrsize)
             if not name.startswith('['):
                 try:
-                    name = os.readlink('/proc/%s/path/%s' % (self.pid, name))
+                    name = os.readlink('/proc/{}/path/{}'.format(self.pid, name))
                 except OSError as err:
                     if err.errno == errno.ENOENT:
                         # sometimes the link may not be resolved by
@@ -524,7 +524,7 @@ class Process(object):
                         # unresolved link path.
                         # This seems an incosistency with /proc similar
                         # to: http://goo.gl/55XgO
-                        name = '/proc/%s/path/%s' % (self.pid, name)
+                        name = '/proc/{}/path/{}'.format(self.pid, name)
                         hit_enoent = True
                     else:
                         raise
diff --git a/python/psutil/psutil/_pswindows.py b/python/psutil/psutil/_pswindows.py
index 2d8babb19c..c609d24441 100644
--- a/python/psutil/psutil/_pswindows.py
+++ b/python/psutil/psutil/_pswindows.py
@@ -16,7 +16,7 @@ from . import _common
 from . import _psutil_windows as cext
 from ._common import conn_tmap, usage_percent, isfile_strict
 from ._common import sockfam_to_enum, socktype_to_enum
-from ._compat import PY3, xrange, lru_cache, long
+from ._compat import PY3, xrange, lru_cache, int
 from ._psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS,
                               BELOW_NORMAL_PRIORITY_CLASS,
                               HIGH_PRIORITY_CLASS,
@@ -143,7 +143,7 @@ def disk_usage(path):
     """Return disk usage associated with path."""
     try:
         total, free = cext.disk_usage(path)
-    except WindowsError:
+    except OSError:
         if not os.path.exists(path):
             msg = "No such file or directory: '%s'" % path
             raise OSError(errno.ENOENT, msg)
@@ -262,7 +262,7 @@ def wrap_exceptions(fun):
     return wrapper
 
 
-class Process(object):
+class Process:
     """Wrapper class around underlying C implementation."""
 
     __slots__ = ["pid", "_name", "_ppid"]
@@ -503,7 +503,7 @@ class Process(object):
     @wrap_exceptions
     def cpu_affinity_get(self):
         def from_bitmask(x):
-            return [i for i in xrange(64) if (1 << i) & x]
+            return [i for i in range(64) if (1 << i) & x]
         bitmask = cext.proc_cpu_affinity_get(self.pid)
         return from_bitmask(bitmask)
 
@@ -523,7 +523,7 @@ class Process(object):
         allcpus = list(range(len(per_cpu_times())))
         for cpu in value:
             if cpu not in allcpus:
-                if not isinstance(cpu, (int, long)):
+                if not isinstance(cpu, int):
                     raise TypeError(
                         "invalid CPU %r; an integer is required" % cpu)
                 else:
diff --git a/python/psutil/setup.py b/python/psutil/setup.py
index 4c42548ef3..1643f48cac 100644
--- a/python/psutil/setup.py
+++ b/python/psutil/setup.py
@@ -22,7 +22,7 @@ HERE = os.path.abspath(os.path.dirname(__file__))
 
 def get_version():
     INIT = os.path.join(HERE, 'psutil/__init__.py')
-    with open(INIT, 'r') as f:
+    with open(INIT) as f:
         for line in f:
             if line.startswith('__version__'):
                 ret = eval(line.strip().split(' = ')[1])
@@ -36,7 +36,7 @@ def get_version():
 
 def get_description():
     README = os.path.join(HERE, 'README.rst')
-    with open(README, 'r') as f:
+    with open(README) as f:
         return f.read()
 
 
diff --git a/python/psutil/test/_bsd.py b/python/psutil/test/_bsd.py
index e4a3225d20..51cf8accd3 100644
--- a/python/psutil/test/_bsd.py
+++ b/python/psutil/test/_bsd.py
@@ -103,9 +103,9 @@ class BSDSpecificTestCase(unittest.TestCase):
             self.assertEqual(usage.total, total)
             # 10 MB tollerance
             if abs(usage.free - free) > 10 * 1024 * 1024:
-                self.fail("psutil=%s, df=%s" % (usage.free, free))
+                self.fail("psutil={}, df={}".format(usage.free, free))
             if abs(usage.used - used) > 10 * 1024 * 1024:
-                self.fail("psutil=%s, df=%s" % (usage.used, used))
+                self.fail("psutil={}, df={}".format(usage.used, used))
 
     @retry_before_failing()
     def test_memory_maps(self):
@@ -117,7 +117,7 @@ class BSDSpecificTestCase(unittest.TestCase):
             fields = line.split()
             _, start, stop, perms, res = fields[:5]
             map = maps.pop()
-            self.assertEqual("%s-%s" % (start, stop), map.addr)
+            self.assertEqual("{}-{}".format(start, stop), map.addr)
             self.assertEqual(int(res), map.rss)
             if not map.path.startswith('['):
                 self.assertEqual(fields[10], map.path)
@@ -243,7 +243,7 @@ class BSDSpecificTestCase(unittest.TestCase):
 
 def main():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(unittest.makeSuite(BSDSpecificTestCase))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(BSDSpecificTestCase))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/_linux.py b/python/psutil/test/_linux.py
index c1927ea8b2..d82313255a 100644
--- a/python/psutil/test/_linux.py
+++ b/python/psutil/test/_linux.py
@@ -6,7 +6,6 @@
 
 """Linux specific tests.  These are implicitly run by test_psutil.py."""
 
-from __future__ import division
 import contextlib
 import errno
 import fcntl
@@ -24,7 +23,7 @@ import warnings
 try:
     from unittest import mock  # py3
 except ImportError:
-    import mock  # requires "pip install mock"
+    from unittest import mock
 
 from test_psutil import POSIX, TOLERANCE, TRAVIS, LINUX
 from test_psutil import (skip_on_not_implemented, sh, get_test_subprocess,
@@ -65,8 +64,8 @@ def get_mac_address(ifname):
             def ord(x):
                 return x
         else:
-            import __builtin__
-            ord = __builtin__.ord
+            import builtins
+            ord = builtins.ord
         return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
 
 
@@ -98,9 +97,9 @@ class LinuxSpecificTestCase(unittest.TestCase):
             self.assertEqual(usage.total, total)
             # 10 MB tollerance
             if abs(usage.free - free) > 10 * 1024 * 1024:
-                self.fail("psutil=%s, df=%s" % (usage.free, free))
+                self.fail("psutil={}, df={}".format(usage.free, free))
             if abs(usage.used - used) > 10 * 1024 * 1024:
-                self.fail("psutil=%s, df=%s" % (usage.used, used))
+                self.fail("psutil={}, df={}".format(usage.used, used))
 
     def test_memory_maps(self):
         sproc = get_test_subprocess()
@@ -176,7 +175,7 @@ class LinuxSpecificTestCase(unittest.TestCase):
     @unittest.skipIf(TRAVIS, "unknown failure on travis")
     def test_cpu_times(self):
         fields = psutil.cpu_times()._fields
-        kernel_ver = re.findall('\d+\.\d+\.\d+', os.uname()[2])[0]
+        kernel_ver = re.findall(r'\d+\.\d+\.\d+', os.uname()[2])[0]
         kernel_ver_info = tuple(map(int, kernel_ver.split('.')))
         if kernel_ver_info >= (2, 6, 11):
             self.assertIn('steal', fields)
@@ -208,11 +207,11 @@ class LinuxSpecificTestCase(unittest.TestCase):
         found = 0
         for line in out.split('\n'):
             line = line.strip()
-            if re.search("^\d+:", line):
+            if re.search(r"^\d+:", line):
                 found += 1
                 name = line.split(':')[1].strip()
-                self.assertIn(name, nics.keys())
-        self.assertEqual(len(nics), found, msg="%s\n---\n%s" % (
+                self.assertIn(name, list(nics.keys()))
+        self.assertEqual(len(nics), found, msg="{}\n---\n{}".format(
             pprint.pformat(nics), out))
 
     @unittest.skipUnless(which("nproc"), "nproc utility not available")
@@ -404,7 +403,7 @@ class LinuxSpecificTestCase(unittest.TestCase):
 
     def test_disk_partitions_mocked(self):
         # Test that ZFS partitions are returned.
-        with open("/proc/filesystems", "r") as f:
+        with open("/proc/filesystems") as f:
             data = f.read()
         if 'zfs' in data:
             for part in psutil.disk_partitions():
@@ -464,7 +463,7 @@ class LinuxSpecificTestCase(unittest.TestCase):
 
 def main():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(unittest.makeSuite(LinuxSpecificTestCase))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(LinuxSpecificTestCase))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/_osx.py b/python/psutil/test/_osx.py
index 6e6e4380ef..30fafea7bb 100644
--- a/python/psutil/test/_osx.py
+++ b/python/psutil/test/_osx.py
@@ -44,7 +44,7 @@ def vm_stat(field):
             break
     else:
         raise ValueError("line not found")
-    return int(re.search('\d+', line).group(0)) * PAGESIZE
+    return int(re.search(r'\d+', line).group(0)) * PAGESIZE
 
 
 @unittest.skipUnless(OSX, "not an OSX system")
@@ -151,7 +151,7 @@ class OSXSpecificTestCase(unittest.TestCase):
 
 def main():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(unittest.makeSuite(OSXSpecificTestCase))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(OSXSpecificTestCase))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/_posix.py b/python/psutil/test/_posix.py
index e6c56aac3e..be9f0d6497 100644
--- a/python/psutil/test/_posix.py
+++ b/python/psutil/test/_posix.py
@@ -192,7 +192,7 @@ class PosixSpecificTestCase(unittest.TestCase):
                     break
             else:
                 self.fail(
-                    "couldn't find %s nic in 'ifconfig -a' output\n%s" % (
+                    "couldn't find {} nic in 'ifconfig -a' output\n{}".format(
                         nic, output))
 
     @retry_before_failing()
@@ -249,7 +249,7 @@ class PosixSpecificTestCase(unittest.TestCase):
 
 def main():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(unittest.makeSuite(PosixSpecificTestCase))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PosixSpecificTestCase))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/_sunos.py b/python/psutil/test/_sunos.py
index 3d54ccd8cf..3f99f01ab5 100644
--- a/python/psutil/test/_sunos.py
+++ b/python/psutil/test/_sunos.py
@@ -39,7 +39,7 @@ class SunOSSpecificTestCase(unittest.TestCase):
 
 def main():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(unittest.makeSuite(SunOSSpecificTestCase))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(SunOSSpecificTestCase))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/_windows.py b/python/psutil/test/_windows.py
index b7477bfeb4..eab325f6fa 100644
--- a/python/psutil/test/_windows.py
+++ b/python/psutil/test/_windows.py
@@ -18,7 +18,7 @@ import traceback
 from test_psutil import APPVEYOR, WINDOWS
 from test_psutil import get_test_subprocess, reap_children, unittest
 
-import mock
+from unittest import mock
 try:
     import wmi
 except ImportError:
@@ -29,7 +29,7 @@ try:
 except ImportError:
     win32api = win32con = None
 
-from psutil._compat import PY3, callable, long
+from psutil._compat import PY3, callable, int
 import psutil
 
 
@@ -91,7 +91,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
         out = p.communicate()[0]
         if PY3:
             out = str(out, sys.stdout.encoding)
-        nics = psutil.net_io_counters(pernic=True).keys()
+        nics = list(psutil.net_io_counters(pernic=True).keys())
         for nic in nics:
             if "pseudo-interface" in nic.replace(' ', '-').lower():
                 continue
@@ -134,7 +134,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
         w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
         p = psutil.Process(self.pid)
         domain, _, username = w.GetOwner()
-        username = "%s\\%s" % (domain, username)
+        username = "{}\\{}".format(domain, username)
         self.assertEqual(p.username(), username)
 
     @unittest.skipIf(wmi is None, "wmi module is not installed")
@@ -157,7 +157,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
         # returned instead.
         wmi_usage = int(w.PageFileUsage)
         if (vms != wmi_usage) and (vms != wmi_usage * 1024):
-            self.fail("wmi=%s, psutil=%s" % (wmi_usage, vms))
+            self.fail("wmi={}, psutil={}".format(wmi_usage, vms))
 
     @unittest.skipIf(wmi is None, "wmi module is not installed")
     def test_process_create_time(self):
@@ -201,7 +201,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
         # Note: this test might fail if the OS is starting/killing
         # other processes in the meantime
         w = wmi.WMI().Win32_Process()
-        wmi_pids = set([x.ProcessId for x in w])
+        wmi_pids = {x.ProcessId for x in w}
         psutil_pids = set(psutil.pids())
         self.assertEqual(wmi_pids, psutil_pids)
 
@@ -228,7 +228,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
                     self.assertEqual(usage.free, wmi_free)
                     # 10 MB tollerance
                     if abs(usage.free - wmi_free) > 10 * 1024 * 1024:
-                        self.fail("psutil=%s, wmi=%s" % (
+                        self.fail("psutil={}, wmi={}".format(
                             usage.free, wmi_free))
                     break
             else:
@@ -282,8 +282,7 @@ class WindowsSpecificTestCase(unittest.TestCase):
             self.fail('\n' + '\n'.join(failures))
 
     def test_name_always_available(self):
-        # On Windows name() is never supposed to raise AccessDenied,
-        # see https://github.com/giampaolo/psutil/issues/627
+        # On Windows name() is never supposed to raise AccessDenied(# see https://github.com/giampaolo/psutil/issues/627)
         for p in psutil.process_iter():
             try:
                 p.name()
@@ -317,7 +316,7 @@ class TestDualProcessImplementation(unittest.TestCase):
             if isinstance(obj, tuple):
                 for value in obj:
                     self.assertGreaterEqual(value, 0, msg=obj)
-            elif isinstance(obj, (int, long, float)):
+            elif isinstance(obj, (int, int, float)):
                 self.assertGreaterEqual(obj, 0)
             else:
                 assert 0  # case not handled which needs to be fixed
@@ -326,7 +325,7 @@ class TestDualProcessImplementation(unittest.TestCase):
             if ret1 == ret2:
                 return
             else:
-                if isinstance(ret2, (int, long, float)):
+                if isinstance(ret2, (int, int, float)):
                     diff = abs(ret1 - ret2)
                     self.assertLessEqual(diff, tolerance)
                 elif isinstance(ret2, tuple):
@@ -376,7 +375,7 @@ class TestDualProcessImplementation(unittest.TestCase):
                         compare_with_tolerance(ret, rawtupl, tolerance)
                 except AssertionError:
                     trace = traceback.format_exc()
-                    msg = '%s\npid=%s, method=%r, ret_1=%r, ret_2=%r' % (
+                    msg = '{}\npid={}, method={!r}, ret_1={!r}, ret_2={!r}'.format(
                         trace, p.pid, name, ret, nt)
                     failures.append(msg)
                     break
@@ -454,8 +453,8 @@ class TestDualProcessImplementation(unittest.TestCase):
 
 def main():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase))
-    test_suite.addTest(unittest.makeSuite(TestDualProcessImplementation))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(WindowsSpecificTestCase))
+    test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestDualProcessImplementation))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/test_memory_leaks.py b/python/psutil/test/test_memory_leaks.py
index 6f02dc0acf..879d3c5748 100644
--- a/python/psutil/test/test_memory_leaks.py
+++ b/python/psutil/test/test_memory_leaks.py
@@ -48,7 +48,7 @@ class Base(unittest.TestCase):
 
     def execute(self, function, *args, **kwargs):
         def call_many_times():
-            for x in xrange(LOOPS - 1):
+            for x in range(LOOPS - 1):
                 self.call(function, *args, **kwargs)
             del x
             gc.collect()
@@ -436,7 +436,7 @@ def main():
              TestProcessObjectLeaks,
              TestModuleFunctionsLeaks]
     for test in tests:
-        test_suite.addTest(unittest.makeSuite(test))
+        test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(test))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/psutil/test/test_psutil.py b/python/psutil/test/test_psutil.py
index 3b2e3587ae..da180081f8 100644
--- a/python/psutil/test/test_psutil.py
+++ b/python/psutil/test/test_psutil.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
@@ -13,7 +12,6 @@ If you're on Python < 2.7 unittest2 module must be installed first:
 https://pypi.python.org/pypi/unittest2
 """
 
-from __future__ import division
 
 import ast
 import atexit
@@ -50,10 +48,10 @@ except ImportError:
 try:
     from unittest import mock  # py3
 except ImportError:
-    import mock  # requires "pip install mock"
+    from unittest import mock
 
 import psutil
-from psutil._compat import PY3, callable, long, unicode
+from psutil._compat import PY3, callable, int, str
 
 if sys.version_info < (2, 7):
     import unittest2 as unittest  # https://pypi.python.org/pypi/unittest2
@@ -85,7 +83,7 @@ TESTFN_UNICODE = TESTFN + "ƒőő"
 TESTFILE_PREFIX = 'psutil-test-suite-'
 if not PY3:
     try:
-        TESTFN_UNICODE = unicode(TESTFN_UNICODE, sys.getfilesystemencoding())
+        TESTFN_UNICODE = str(TESTFN_UNICODE, sys.getfilesystemencoding())
     except UnicodeDecodeError:
         TESTFN_UNICODE = TESTFN + "???"
 
@@ -273,14 +271,14 @@ def wait_for_file(fname, timeout=GLOBAL_TIMEOUT, delete_file=True):
     stop_at = time.time() + 3
     while time.time() < stop_at:
         try:
-            with open(fname, "r") as f:
+            with open(fname) as f:
                 data = f.read()
             if not data:
                 continue
             if delete_file:
                 os.remove(fname)
             return data
-        except IOError:
+        except OSError:
             time.sleep(0.001)
     raise RuntimeError("timed out (couldn't read file)")
 
@@ -325,16 +323,16 @@ def check_ip_address(addr, family):
             assert 0 <= num <= 255, addr
         if ipaddress:
             if not PY3:
-                addr = unicode(addr)
+                addr = str(addr)
             ipaddress.IPv4Address(addr)
     elif family == AF_INET6:
         assert isinstance(addr, str), addr
         if ipaddress:
             if not PY3:
-                addr = unicode(addr)
+                addr = str(addr)
             ipaddress.IPv6Address(addr)
     elif family == psutil.AF_LINK:
-        assert re.match('([a-fA-F0-9]{2}[:|\-]?){6}', addr) is not None, addr
+        assert re.match(r'([a-fA-F0-9]{2}[:|\-]?){6}', addr) is not None, addr
     else:
         raise ValueError("unknown family %r", family)
 
@@ -378,7 +376,7 @@ def check_connection_ntuple(conn):
             with contextlib.closing(s):
                 try:
                     s.bind((conn.laddr[0], 0))
-                except socket.error as err:
+                except OSError as err:
                     if err.errno != errno.EADDRNOTAVAIL:
                         raise
     elif conn.family == AF_UNIX:
@@ -390,7 +388,7 @@ def check_connection_ntuple(conn):
         if hasattr(socket, 'fromfd') and not WINDOWS:
             try:
                 dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
-            except (socket.error, OSError) as err:
+            except OSError as err:
                 if err.args[0] != errno.EBADF:
                     raise
             else:
@@ -494,7 +492,7 @@ def supports_ipv6():
     try:
         sock = socket.socket(AF_INET6, SOCK_STREAM)
         sock.bind(("::1", 0))
-    except (socket.error, socket.gaierror):
+    except (OSError, socket.gaierror):
         return False
     else:
         return True
@@ -509,7 +507,7 @@ if WINDOWS:
         if hasattr(wv, 'service_pack_major'):  # python >= 2.7
             sp = wv.service_pack_major or 0
         else:
-            r = re.search("\s\d$", wv[4])
+            r = re.search(r"\s\d$", wv[4])
             if r:
                 sp = int(r.group(0))
             else:
@@ -528,7 +526,7 @@ class ThreadTask(threading.Thread):
 
     def __repr__(self):
         name = self.__class__.__name__
-        return '<%s running=%s at %#x>' % (name, self._running, id(self))
+        return '<{} running={} at {:#x}>'.format(name, self._running, id(self))
 
     def start(self, interval=0.001):
         """Start thread and keep it running until an explicit
@@ -627,7 +625,7 @@ class TestSystemAPIs(unittest.TestCase):
         sproc1.terminate()
         sproc2.terminate()
         gone, alive = test(procs, callback)
-        self.assertEqual(set(l), set([sproc1.pid, sproc2.pid, sproc3.pid]))
+        self.assertEqual(set(l), {sproc1.pid, sproc2.pid, sproc3.pid})
         for p in gone:
             self.assertTrue(hasattr(p, 'returncode'))
 
@@ -664,10 +662,10 @@ class TestSystemAPIs(unittest.TestCase):
         for name in mem._fields:
             value = getattr(mem, name)
             if name != 'percent':
-                self.assertIsInstance(value, (int, long))
+                self.assertIsInstance(value, int)
             if name != 'total':
                 if not value >= 0:
-                    self.fail("%r < 0 (%s)" % (name, value))
+                    self.fail("{!r} < 0 ({})".format(name, value))
                 if value > mem.total:
                     self.fail("%r > total (total=%s, %s=%s)"
                               % (name, mem.total, name, value))
@@ -709,7 +707,7 @@ class TestSystemAPIs(unittest.TestCase):
                 time.sleep(.1)
                 if pid in psutil.pids():
                     self.fail(pid)
-        pids = range(max(pids) + 5000, max(pids) + 6000)
+        pids = list(range(max(pids) + 5000, max(pids) + 6000))
         for pid in pids:
             self.assertFalse(psutil.pid_exists(pid), msg=pid)
 
@@ -764,7 +762,7 @@ class TestSystemAPIs(unittest.TestCase):
                     new_t = getattr(new, field)
                     last_t = getattr(last, field)
                     self.assertGreaterEqual(new_t, last_t,
-                                            msg="%s %s" % (new_t, last_t))
+                                            msg="{} {}".format(new_t, last_t))
                 last = new
 
     def test_sys_cpu_times2(self):
@@ -828,7 +826,7 @@ class TestSystemAPIs(unittest.TestCase):
             self.assertIsNot(percent, -0.0)
             self.assertLessEqual(percent, 100.0 * psutil.cpu_count())
         except AssertionError as err:
-            raise AssertionError("\n%s\nlast=%s\nnew=%s" % (
+            raise AssertionError("\n{}\nlast={}\nnew={}".format(
                 err, pprint.pformat(last_ret), pprint.pformat(new_ret)))
 
     def test_sys_cpu_percent(self):
@@ -1034,7 +1032,7 @@ class TestSystemAPIs(unittest.TestCase):
         # self.assertEqual(sorted(nics.keys()),
         #                  sorted(psutil.net_io_counters(pernic=True).keys()))
 
-        families = set([socket.AF_INET, AF_INET6, psutil.AF_LINK])
+        families = {socket.AF_INET, AF_INET6, psutil.AF_LINK}
         for nic, addrs in nics.items():
             self.assertEqual(len(set(addrs)), len(addrs))
             for addr in addrs:
@@ -1120,7 +1118,7 @@ class TestSystemAPIs(unittest.TestCase):
                 # https://github.com/giampaolo/psutil/issues/338
                 while key[-1].isdigit():
                     key = key[:-1]
-                self.assertNotIn(key, ret.keys())
+                self.assertNotIn(key, list(ret.keys()))
 
     def test_users(self):
         users = psutil.users()
@@ -1326,10 +1324,10 @@ class TestProcess(unittest.TestCase):
         # using a tolerance  of +/- 0.1 seconds.
         # It will fail if the difference between the values is > 0.1s.
         if (max([user_time, utime]) - min([user_time, utime])) > 0.1:
-            self.fail("expected: %s, found: %s" % (utime, user_time))
+            self.fail("expected: {}, found: {}".format(utime, user_time))
 
         if (max([kernel_time, ktime]) - min([kernel_time, ktime])) > 0.1:
-            self.fail("expected: %s, found: %s" % (ktime, kernel_time))
+            self.fail("expected: {}, found: {}".format(ktime, kernel_time))
 
     def test_create_time(self):
         sproc = get_test_subprocess(wait=True)
@@ -1422,13 +1420,13 @@ class TestProcess(unittest.TestCase):
                 self.assertRaises(ValueError, p.ionice, 2, -1)
                 self.assertRaises(ValueError, p.ionice, 4)
                 self.assertRaises(TypeError, p.ionice, 2, "foo")
-                self.assertRaisesRegexp(
+                self.assertRaisesRegex(
                     ValueError, "can't specify value with IOPRIO_CLASS_NONE",
                     p.ionice, psutil.IOPRIO_CLASS_NONE, 1)
-                self.assertRaisesRegexp(
+                self.assertRaisesRegex(
                     ValueError, "can't specify value with IOPRIO_CLASS_IDLE",
                     p.ionice, psutil.IOPRIO_CLASS_IDLE, 1)
-                self.assertRaisesRegexp(
+                self.assertRaisesRegex(
                     ValueError, "'ioclass' argument must be specified",
                     p.ionice, value=1)
             finally:
@@ -1578,7 +1576,7 @@ class TestProcess(unittest.TestCase):
                 elif fname in ('addr', 'perms'):
                     assert value, value
                 else:
-                    self.assertIsInstance(value, (int, long))
+                    self.assertIsInstance(value, int)
                     assert value >= 0, value
 
     def test_memory_percent(self):
@@ -1611,7 +1609,7 @@ class TestProcess(unittest.TestCase):
                 # "/usr/local/bin/python"
                 # We do not want to consider this difference in accuracy
                 # an error.
-                ver = "%s.%s" % (sys.version_info[0], sys.version_info[1])
+                ver = "{}.{}".format(sys.version_info[0], sys.version_info[1])
                 self.assertEqual(exe.replace(ver, ''), PYTHON.replace(ver, ''))
 
     def test_cmdline(self):
@@ -1779,7 +1777,7 @@ class TestProcess(unittest.TestCase):
         p.cpu_affinity(tuple(all_cpus))
         invalid_cpu = [len(psutil.cpu_times(percpu=True)) + 10]
         self.assertRaises(ValueError, p.cpu_affinity, invalid_cpu)
-        self.assertRaises(ValueError, p.cpu_affinity, range(10000, 11000))
+        self.assertRaises(ValueError, p.cpu_affinity, list(range(10000, 11000)))
         self.assertRaises(TypeError, p.cpu_affinity, [0, "1"])
 
     # TODO
@@ -2085,7 +2083,7 @@ class TestProcess(unittest.TestCase):
             except psutil.Error:
                 pass
         # this is the one, now let's make sure there are no duplicates
-        pid = sorted(table.items(), key=lambda x: x[1])[-1][0]
+        pid = sorted(list(table.items()), key=lambda x: x[1])[-1][0]
         p = psutil.Process(pid)
         try:
             c = p.children(recursive=True)
@@ -2173,7 +2171,7 @@ class TestProcess(unittest.TestCase):
                 pass
             else:
                 self.fail(
-                    "NoSuchProcess exception not raised for %r, retval=%s" % (
+                    "NoSuchProcess exception not raised for {!r}, retval={}".format(
                         name, ret))
 
     @unittest.skipUnless(POSIX, 'posix only')
@@ -2280,7 +2278,7 @@ class TestProcess(unittest.TestCase):
             except psutil.AccessDenied:
                 pass
 
-            self.assertRaisesRegexp(
+            self.assertRaisesRegex(
                 ValueError, "preventing sending signal to process with PID 0",
                 p.send_signal, signal.SIGTERM)
 
@@ -2344,14 +2342,14 @@ class TestFetchAllProcesses(unittest.TestCase):
         if POSIX:
             import pwd
             pall = pwd.getpwall()
-            self._uids = set([x.pw_uid for x in pall])
-            self._usernames = set([x.pw_name for x in pall])
+            self._uids = {x.pw_uid for x in pall}
+            self._usernames = {x.pw_name for x in pall}
 
     def test_fetch_all(self):
         valid_procs = 0
-        excluded_names = set([
+        excluded_names = {
             'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
-            'as_dict', 'cpu_percent', 'parent', 'children', 'pid'])
+            'as_dict', 'cpu_percent', 'parent', 'children', 'pid'}
         if LINUX and not RLIMIT_SUPPORT:
             excluded_names.add('rlimit')
         attrs = []
@@ -2397,7 +2395,7 @@ class TestFetchAllProcesses(unittest.TestCase):
                         meth(ret)
                 except Exception as err:
                     s = '\n' + '=' * 70 + '\n'
-                    s += "FAIL: test_%s (proc=%s" % (name, p)
+                    s += "FAIL: test_{} (proc={}".format(name, p)
                     if ret != default:
                         s += ", ret=%s)" % repr(ret)
                     s += ')\n'
@@ -2434,7 +2432,7 @@ class TestFetchAllProcesses(unittest.TestCase):
         self.assertTrue(ret >= 0)
 
     def name(self, ret):
-        self.assertIsInstance(ret, (str, unicode))
+        self.assertIsInstance(ret, (str, str))
         self.assertTrue(ret)
 
     def create_time(self, ret):
@@ -2568,7 +2566,7 @@ class TestFetchAllProcesses(unittest.TestCase):
                 elif fname in ('addr', 'perms'):
                     self.assertTrue(value)
                 else:
-                    self.assertIsInstance(value, (int, long))
+                    self.assertIsInstance(value, int)
                     assert value >= 0, value
 
     def num_handles(self, ret):
@@ -2743,7 +2741,7 @@ class TestMisc(unittest.TestCase):
         self.assertNotEqual(p1, 'foo')
 
     def test_process__hash__(self):
-        s = set([psutil.Process(), psutil.Process()])
+        s = {psutil.Process(), psutil.Process()}
         self.assertEqual(len(s), 1)
 
     def test__all__(self):
@@ -2901,7 +2899,7 @@ class TestExampleScripts(unittest.TestCase):
 
     def assert_syntax(self, exe, args=None):
         exe = os.path.join(EXAMPLES_DIR, exe)
-        with open(exe, 'r') as f:
+        with open(exe) as f:
             src = f.read()
         ast.parse(src)
 
@@ -3004,7 +3002,7 @@ def main():
         tests.append(stc)
 
     for test_class in tests:
-        test_suite.addTest(unittest.makeSuite(test_class))
+        test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(test_class))
     result = unittest.TextTestRunner(verbosity=2).run(test_suite)
     return result.wasSuccessful()
 
diff --git a/python/py/py/_apipkg.py b/python/py/py/_apipkg.py
index a73b8f6d0b..ae24a8b33a 100644
--- a/python/py/py/_apipkg.py
+++ b/python/py/py/_apipkg.py
@@ -77,7 +77,7 @@ class ApiModule(ModuleType):
                 setattr(self, name, val)
         for name, importspec in importspec.items():
             if isinstance(importspec, dict):
-                subname = '%s.%s' % (self.__name__, name)
+                subname = '{}.{}'.format(self.__name__, name)
                 apimod = ApiModule(subname, importspec, implprefix)
                 sys.modules[subname] = apimod
                 setattr(self, name, apimod)
@@ -89,7 +89,7 @@ class ApiModule(ModuleType):
                     modpath = implprefix + modpath
 
                 if not attrname:
-                    subname = '%s.%s' % (self.__name__, name)
+                    subname = '{}.{}'.format(self.__name__, name)
                     apimod = AliasModule(subname, modpath)
                     sys.modules[subname] = apimod
                     if '.' not in name:
@@ -104,8 +104,8 @@ class ApiModule(ModuleType):
         if hasattr(self, '__file__'):
             l.append('from ' + repr(self.__file__))
         if l:
-            return '' % (self.__name__, " ".join(l))
-        return '' % (self.__name__,)
+            return ''.format(self.__name__, " ".join(l))
+        return ''.format(self.__name__)
 
     def __makeattr(self, name):
         """lazily compute value for name or raise AttributeError if unknown."""
@@ -164,7 +164,7 @@ def AliasModule(modname, modpath, attrname=None):
             x = modpath
             if attrname:
                 x += "." + attrname
-            return '' % (modname, x)
+            return ''.format(modname, x)
 
         def __getattribute__(self, name):
             try:
diff --git a/python/py/py/_builtin.py b/python/py/py/_builtin.py
index 52ee9d79ca..ba30137a15 100644
--- a/python/py/py/_builtin.py
+++ b/python/py/py/_builtin.py
@@ -14,7 +14,7 @@ except NameError:
             raise TypeError("argument to reversed() must be a sequence")
         return reversed_iterator(sequence)
 
-    class reversed_iterator(object):
+    class reversed_iterator:
 
         def __init__(self, seq):
             self.seq = seq
@@ -113,127 +113,60 @@ except NameError:
     def callable(obj):
         return hasattr(obj, "__call__")
 
-if sys.version_info >= (3, 0):
-    exec ("print_ = print ; exec_=exec")
-    import builtins
+exec ("print_ = print ; exec_=exec")
+import builtins
 
-    # some backward compatibility helpers
-    _basestring = str
-    def _totext(obj, encoding=None, errors=None):
-        if isinstance(obj, bytes):
-            if errors is None:
-                obj = obj.decode(encoding)
-            else:
-                obj = obj.decode(encoding, errors)
-        elif not isinstance(obj, str):
-            obj = str(obj)
-        return obj
-
-    def _isbytes(x):
-        return isinstance(x, bytes)
-    def _istext(x):
-        return isinstance(x, str)
-
-    text = str
-    bytes = bytes
-
-
-    def _getimself(function):
-        return getattr(function, '__self__', None)
-
-    def _getfuncdict(function):
-        return getattr(function, "__dict__", None)
-
-    def _getcode(function):
-        return getattr(function, "__code__", None)
-
-    def execfile(fn, globs=None, locs=None):
-        if globs is None:
-            back = sys._getframe(1)
-            globs = back.f_globals
-            locs = back.f_locals
-            del back
-        elif locs is None:
-            locs = globs
-        fp = open(fn, "r")
-        try:
-            source = fp.read()
-        finally:
-            fp.close()
-        co = compile(source, fn, "exec", dont_inherit=True)
-        exec_(co, globs, locs)
-
-else:
-    import __builtin__ as builtins
-    _totext = unicode
-    _basestring = basestring
-    text = unicode
-    bytes = str
-    execfile = execfile
-    callable = callable
-    def _isbytes(x):
-        return isinstance(x, str)
-    def _istext(x):
-        return isinstance(x, unicode)
-
-    def _getimself(function):
-        return getattr(function, 'im_self', None)
+# some backward compatibility helpers
+_basestring = str
+def _totext(obj, encoding=None, errors=None):
+    if isinstance(obj, bytes):
+        if errors is None:
+            obj = obj.decode(encoding)
+        else:
+            obj = obj.decode(encoding, errors)
+    elif not isinstance(obj, str):
+        obj = str(obj)
+    return obj
+
+def _isbytes(x):
+    return isinstance(x, bytes)
+def _istext(x):
+    return isinstance(x, str)
+
+text = str
+bytes = bytes
+
+
+def _getimself(function):
+    return getattr(function, '__self__', None)
+
+def _getfuncdict(function):
+    return getattr(function, "__dict__", None)
+
+def _getcode(function):
+    return getattr(function, "__code__", None)
+
+def execfile(fn, globs=None, locs=None):
+    if globs is None:
+        back = sys._getframe(1)
+        globs = back.f_globals
+        locs = back.f_locals
+        del back
+    elif locs is None:
+        locs = globs
+    fp = open(fn)
+    try:
+        source = fp.read()
+    finally:
+        fp.close()
+    co = compile(source, fn, "exec", dont_inherit=True)
+    exec_(co, globs, locs)
 
-    def _getfuncdict(function):
-        return getattr(function, "__dict__", None)
 
-    def _getcode(function):
-        try:
-            return getattr(function, "__code__")
-        except AttributeError:
-            return getattr(function, "func_code", None)
-
-    def print_(*args, **kwargs):
-        """ minimal backport of py3k print statement. """
-        sep = ' '
-        if 'sep' in kwargs:
-            sep = kwargs.pop('sep')
-        end = '\n'
-        if 'end' in kwargs:
-            end = kwargs.pop('end')
-        file = 'file' in kwargs and kwargs.pop('file') or sys.stdout
-        if kwargs:
-            args = ", ".join([str(x) for x in kwargs])
-            raise TypeError("invalid keyword arguments: %s" % args)
-        at_start = True
-        for x in args:
-            if not at_start:
-                file.write(sep)
-            file.write(str(x))
-            at_start = False
-        file.write(end)
-
-    def exec_(obj, globals=None, locals=None):
-        """ minimal backport of py3k exec statement. """
-        __tracebackhide__ = True
-        if globals is None:
-            frame = sys._getframe(1)
-            globals = frame.f_globals
-            if locals is None:
-                locals = frame.f_locals
-        elif locals is None:
-            locals = globals
-        exec2(obj, globals, locals)
-
-if sys.version_info >= (3, 0):
-    def _reraise(cls, val, tb):
-        __tracebackhide__ = True
-        assert hasattr(val, '__traceback__')
-        raise cls.with_traceback(val, tb)
-else:
-    exec ("""
 def _reraise(cls, val, tb):
     __tracebackhide__ = True
-    raise cls, val, tb
-def exec2(obj, globals, locals):
-    __tracebackhide__ = True
-    exec obj in globals, locals
-""")
+    assert hasattr(val, '__traceback__')
+    raise cls.with_traceback(val, tb)
 
 def _tryimport(*names):
     """ return the first successfully imported module. """
diff --git a/python/py/py/_code/_assertionnew.py b/python/py/py/_code/_assertionnew.py
index afb1b31ff0..89fb792bd5 100644
--- a/python/py/py/_code/_assertionnew.py
+++ b/python/py/py/_code/_assertionnew.py
@@ -20,8 +20,8 @@ if sys.platform.startswith("java") and sys.version_info < (2, 5, 2):
               "AugAssign", "Print", "For", "While", "If", "With", "Raise",
               "TryExcept", "TryFinally", "Assert", "Import", "ImportFrom",
               "Exec", "Global", "Expr", "Pass", "Break", "Continue")
-    _expr_nodes = set(getattr(ast, name) for name in _exprs)
-    _stmt_nodes = set(getattr(ast, name) for name in _stmts)
+    _expr_nodes = {getattr(ast, name) for name in _exprs}
+    _stmt_nodes = {getattr(ast, name) for name in _stmts}
     def _is_ast_expr(node):
         return node.__class__ in _expr_nodes
     def _is_ast_stmt(node):
@@ -66,9 +66,9 @@ def getfailure(failure):
         lines = explanation.splitlines()
         if not lines:
             lines.append("")
-        lines[0] += " << %s" % (value,)
+        lines[0] += " << {}".format(value)
         explanation = "\n".join(lines)
-    text = "%s: %s" % (failure.cause[0].__name__, explanation)
+    text = "{}: {}".format(failure.cause[0].__name__, explanation)
     if text.startswith("AssertionError: assert "):
         text = text[16:]
     return text
@@ -148,7 +148,7 @@ class DebugInterpreter(ast.NodeVisitor):
     def visit_Name(self, name):
         explanation, result = self.generic_visit(name)
         # See if the name is local.
-        source = "%r in locals() is not globals()" % (name.id,)
+        source = "{!r} in locals() is not globals()".format(name.id)
         co = self._compile(source)
         try:
             local = self.frame.eval(co)
@@ -165,9 +165,9 @@ class DebugInterpreter(ast.NodeVisitor):
         for op, next_op in zip(comp.ops, comp.comparators):
             next_explanation, next_result = self.visit(next_op)
             op_symbol = operator_map[op.__class__]
-            explanation = "%s %s %s" % (left_explanation, op_symbol,
+            explanation = "{} {} {}".format(left_explanation, op_symbol,
                                         next_explanation)
-            source = "__exprinfo_left %s __exprinfo_right" % (op_symbol,)
+            source = "__exprinfo_left {} __exprinfo_right".format(op_symbol)
             co = self._compile(source)
             try:
                 result = self.frame.eval(co, __exprinfo_left=left_result,
@@ -217,9 +217,9 @@ class DebugInterpreter(ast.NodeVisitor):
         left_explanation, left_result = self.visit(binop.left)
         right_explanation, right_result = self.visit(binop.right)
         symbol = operator_map[binop.op.__class__]
-        explanation = "(%s %s %s)" % (left_explanation, symbol,
+        explanation = "({} {} {})".format(left_explanation, symbol,
                                       right_explanation)
-        source = "__exprinfo_left %s __exprinfo_right" % (symbol,)
+        source = "__exprinfo_left {} __exprinfo_right".format(symbol)
         co = self._compile(source)
         try:
             result = self.frame.eval(co, __exprinfo_left=left_result,
@@ -235,13 +235,13 @@ class DebugInterpreter(ast.NodeVisitor):
         arguments = []
         for arg in call.args:
             arg_explanation, arg_result = self.visit(arg)
-            arg_name = "__exprinfo_%s" % (len(ns),)
+            arg_name = "__exprinfo_{}".format(len(ns))
             ns[arg_name] = arg_result
             arguments.append(arg_name)
             arg_explanations.append(arg_explanation)
         for keyword in call.keywords:
             arg_explanation, arg_result = self.visit(keyword.value)
-            arg_name = "__exprinfo_%s" % (len(ns),)
+            arg_name = "__exprinfo_{}".format(len(ns))
             ns[arg_name] = arg_result
             keyword_source = "%s=%%s" % (keyword.arg)
             arguments.append(keyword_source % (arg_name,))
@@ -250,18 +250,18 @@ class DebugInterpreter(ast.NodeVisitor):
             arg_explanation, arg_result = self.visit(call.starargs)
             arg_name = "__exprinfo_star"
             ns[arg_name] = arg_result
-            arguments.append("*%s" % (arg_name,))
-            arg_explanations.append("*%s" % (arg_explanation,))
+            arguments.append("*{}".format(arg_name))
+            arg_explanations.append("*{}".format(arg_explanation))
         if call.kwargs:
             arg_explanation, arg_result = self.visit(call.kwargs)
             arg_name = "__exprinfo_kwds"
             ns[arg_name] = arg_result
-            arguments.append("**%s" % (arg_name,))
-            arg_explanations.append("**%s" % (arg_explanation,))
+            arguments.append("**{}".format(arg_name))
+            arg_explanations.append("**{}".format(arg_explanation))
         args_explained = ", ".join(arg_explanations)
-        explanation = "%s(%s)" % (func_explanation, args_explained)
+        explanation = "{}({})".format(func_explanation, args_explained)
         args = ", ".join(arguments)
-        source = "__exprinfo_func(%s)" % (args,)
+        source = "__exprinfo_func({})".format(args)
         co = self._compile(source)
         try:
             result = self.frame.eval(co, **ns)
@@ -285,14 +285,14 @@ class DebugInterpreter(ast.NodeVisitor):
         if not isinstance(attr.ctx, ast.Load):
             return self.generic_visit(attr)
         source_explanation, source_result = self.visit(attr.value)
-        explanation = "%s.%s" % (source_explanation, attr.attr)
-        source = "__exprinfo_expr.%s" % (attr.attr,)
+        explanation = "{}.{}".format(source_explanation, attr.attr)
+        source = "__exprinfo_expr.{}".format(attr.attr)
         co = self._compile(source)
         try:
             result = self.frame.eval(co, __exprinfo_expr=source_result)
         except Exception:
             raise Failure(explanation)
-        explanation = "%s\n{%s = %s.%s\n}" % (self.frame.repr(result),
+        explanation = "{}\n{{{} = {}.{}\n}}".format(self.frame.repr(result),
                                               self.frame.repr(result),
                                               source_explanation, attr.attr)
         # Check if the attr is from an instance.
@@ -314,7 +314,7 @@ class DebugInterpreter(ast.NodeVisitor):
         if test_explanation.startswith("False\n{False =") and \
                 test_explanation.endswith("\n"):
             test_explanation = test_explanation[15:-2]
-        explanation = "assert %s" % (test_explanation,)
+        explanation = "assert {}".format(test_explanation)
         if not test_result:
             try:
                 raise BuiltinAssertionError
@@ -324,7 +324,7 @@ class DebugInterpreter(ast.NodeVisitor):
 
     def visit_Assign(self, assign):
         value_explanation, value_result = self.visit(assign.value)
-        explanation = "... = %s" % (value_explanation,)
+        explanation = "... = {}".format(value_explanation)
         name = ast.Name("__exprinfo_expr", ast.Load(),
                         lineno=assign.value.lineno,
                         col_offset=assign.value.col_offset)
diff --git a/python/py/py/_code/_assertionold.py b/python/py/py/_code/_assertionold.py
index 4e81fb3ef6..5a623b7835 100644
--- a/python/py/py/_code/_assertionold.py
+++ b/python/py/py/_code/_assertionold.py
@@ -10,7 +10,7 @@ class Failure:
         self.exc, self.value, self.tb = sys.exc_info()
         self.node = node
 
-class View(object):
+class View:
     """View base class.
 
     If C is a subclass of View, then C(x) creates a proxy object around
@@ -86,13 +86,12 @@ class View(object):
             return type('?', tuple(choices), {})
 
     def __repr__(self):
-        return '%s(%r)' % (self.__rootclass__.__name__, self.__obj__)
+        return '{}({!r})'.format(self.__rootclass__.__name__, self.__obj__)
 
 
 def enumsubclasses(cls):
     for subcls in cls.__subclasses__():
-        for subsubclass in enumsubclasses(subcls):
-            yield subsubclass
+        yield from enumsubclasses(subcls)
     yield cls
 
 
@@ -156,7 +155,7 @@ class Name(Interpretable):
             return False
 
     def is_builtin(self, frame):
-        source = '%r not in locals() and %r not in globals()' % (
+        source = '{!r} not in locals() and {!r} not in globals()'.format(
             self.name, self.name)
         try:
             return frame.is_true(frame.eval(source))
@@ -166,7 +165,7 @@ class Name(Interpretable):
             return False
 
     def eval(self, frame):
-        super(Name, self).eval(frame)
+        super().eval(frame)
         if not self.is_local(frame):
             self.explanation = self.name
 
@@ -183,7 +182,7 @@ class Compare(Interpretable):
                     break
             expr2 = Interpretable(expr2)
             expr2.eval(frame)
-            self.explanation = "%s %s %s" % (
+            self.explanation = "{} {} {}".format(
                 expr.explanation, operation, expr2.explanation)
             source = "__exprinfo_left %s __exprinfo_right" % operation
             try:
@@ -316,8 +315,8 @@ class CallFunc(Interpretable):
                 source += argname + ','
                 explanations.append(a.explanation)
             else:
-                source += '%s=%s,' % (keyword, argname)
-                explanations.append('%s=%s' % (keyword, a.explanation))
+                source += '{}={},'.format(keyword, argname)
+                explanations.append('{}={}'.format(keyword, a.explanation))
         if self.star_args:
             star_args = Interpretable(self.star_args)
             star_args.eval(frame)
@@ -332,7 +331,7 @@ class CallFunc(Interpretable):
             vars[argname] = dstar_args.result
             source += '**' + argname + ','
             explanations.append('**' + dstar_args.explanation)
-        self.explanation = "%s(%s)" % (
+        self.explanation = "{}({})".format(
             node.explanation, ', '.join(explanations))
         if source.endswith(','):
             source = source[:-1]
@@ -345,7 +344,7 @@ class CallFunc(Interpretable):
             raise Failure(self)
         if not node.is_builtin(frame) or not self.is_bool(frame):
             r = frame.repr(self.result)
-            self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation)
+            self.explanation = '{}\n{{{} = {}\n}}'.format(r, r, self.explanation)
 
 class Getattr(Interpretable):
     __view__ = ast.Getattr
@@ -360,7 +359,7 @@ class Getattr(Interpretable):
             raise
         except:
             raise Failure(self)
-        self.explanation = '%s.%s' % (expr.explanation, self.attrname)
+        self.explanation = '{}.{}'.format(expr.explanation, self.attrname)
         # if the attribute comes from the instance, its value is interesting
         source = ('hasattr(__exprinfo_expr, "__dict__") and '
                   '%r in __exprinfo_expr.__dict__' % self.attrname)
@@ -373,7 +372,7 @@ class Getattr(Interpretable):
             from_instance = True
         if from_instance:
             r = frame.repr(self.result)
-            self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation)
+            self.explanation = '{}\n{{{} = {}\n}}'.format(r, r, self.explanation)
 
 # == Re-interpretation of full statements ==
 
@@ -442,7 +441,7 @@ def report_failure(e):
         explanation = ", in: " + explanation
     else:
         explanation = ""
-    sys.stdout.write("%s: %s%s\n" % (e.exc.__name__, e.value, explanation))
+    sys.stdout.write("{}: {}{}\n".format(e.exc.__name__, e.value, explanation))
 
 def check(s, frame=None):
     if frame is None:
@@ -500,16 +499,16 @@ def getmsg(excinfo):
     source = str(tb.statement).strip()
     x = interpret(source, tb.frame, should_fail=True)
     if not isinstance(x, str):
-        raise TypeError("interpret returned non-string %r" % (x,))
+        raise TypeError("interpret returned non-string {!r}".format(x))
     return x
 
 def getfailure(e):
     explanation = e.node.nice_explanation()
     if str(e.value):
         lines = explanation.split('\n')
-        lines[0] += "  << %s" % (e.value,)
+        lines[0] += "  << {}".format(e.value)
         explanation = '\n'.join(lines)
-    text = "%s: %s" % (e.exc.__name__, explanation)
+    text = "{}: {}".format(e.exc.__name__, explanation)
     if text.startswith('AssertionError: assert '):
         text = text[16:]
     return text
diff --git a/python/py/py/_code/_py2traceback.py b/python/py/py/_code/_py2traceback.py
index d65e27cb73..e624c243ac 100644
--- a/python/py/py/_code/_py2traceback.py
+++ b/python/py/py/_code/_py2traceback.py
@@ -23,7 +23,7 @@ def format_exception_only(etype, value):
 
     # An instance should not have a meaningful value parameter, but
     # sometimes does, particularly for string exceptions, such as
-    # >>> raise string1, string2  # deprecated
+    # >>> raise string1(string2  # deprecated)
     #
     # Clear these out first because issubtype(string1, SyntaxError)
     # would throw another exception and mask the original problem.
@@ -65,12 +65,12 @@ def _format_final_exc_line(etype, value):
     if value is None or not valuestr:
         line = "%s\n" % etype
     else:
-        line = "%s: %s\n" % (etype, valuestr)
+        line = "{}: {}\n".format(etype, valuestr)
     return line
 
 def _some_str(value):
     try:
-        return unicode(value)
+        return str(value)
     except Exception:
         try:
             return str(value)
diff --git a/python/py/py/_code/assertion.py b/python/py/py/_code/assertion.py
index 4ce80c75b1..89824382f0 100644
--- a/python/py/py/_code/assertion.py
+++ b/python/py/py/_code/assertion.py
@@ -82,11 +82,8 @@ class AssertionError(BuiltinAssertionError):
             if not self.args:
                 self.args = (self.msg,)
 
-if sys.version_info > (3, 0):
-    AssertionError.__module__ = "builtins"
-    reinterpret_old = "old reinterpretation not available for py3"
-else:
-    from py._code._assertionold import interpret as reinterpret_old
+AssertionError.__module__ = "builtins"
+reinterpret_old = "old reinterpretation not available for py3"
 if sys.version_info >= (2, 6) or (sys.platform.startswith("java")):
     from py._code._assertionnew import interpret as reinterpret
 else:
diff --git a/python/py/py/_code/code.py b/python/py/py/_code/code.py
index f14c562a29..0b29de99c4 100644
--- a/python/py/py/_code/code.py
+++ b/python/py/py/_code/code.py
@@ -6,12 +6,9 @@ builtin_repr = repr
 
 reprlib = py.builtin._tryimport('repr', 'reprlib')
 
-if sys.version_info[0] >= 3:
-    from traceback import format_exception_only
-else:
-    from py._code._py2traceback import format_exception_only
+from traceback import format_exception_only
 
-class Code(object):
+class Code:
     """ wrapper around Python code objects """
     def __init__(self, rawcode):
         if not hasattr(rawcode, "co_filename"):
@@ -70,7 +67,7 @@ class Code(object):
             argcount += raw.co_flags & CO_VARKEYWORDS
         return raw.co_varnames[:argcount]
 
-class Frame(object):
+class Frame:
     """Wrapper around a Python frame holding f_locals and f_globals
     in which expressions can be evaluated."""
 
@@ -130,7 +127,7 @@ class Frame(object):
                 pass     # this can occur when using Psyco
         return retval
 
-class TracebackEntry(object):
+class TracebackEntry:
     """ a single entry in a traceback """
 
     _repr_style = None
@@ -177,7 +174,7 @@ class TracebackEntry(object):
             source = str(self.statement).strip()
             x = py.code._reinterpret(source, self.frame, should_fail=True)
             if not isinstance(x, str):
-                raise TypeError("interpret returned non-string %r" % (x,))
+                raise TypeError("interpret returned non-string {!r}".format(x))
             self.exprinfo = x
         return self.exprinfo
 
@@ -281,7 +278,7 @@ class Traceback(list):
         return self
 
     def __getitem__(self, key):
-        val = super(Traceback, self).__getitem__(key)
+        val = super().__getitem__(key)
         if isinstance(key, type(slice(0))):
             val = self.__class__(val)
         return val
@@ -296,7 +293,7 @@ class Traceback(list):
             by default this removes all the TracebackItems which are hidden
             (see ishidden() above)
         """
-        return Traceback(filter(fn, self))
+        return Traceback(list(filter(fn, self)))
 
     def getcrashentry(self):
         """ return last non-hidden traceback entry that lead
@@ -335,7 +332,7 @@ class Traceback(list):
 co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2',
                    '?', 'eval')
 
-class ExceptionInfo(object):
+class ExceptionInfo:
     """ wraps sys.exc_info() objects and offers
         help for navigating the traceback.
     """
@@ -419,10 +416,10 @@ class ExceptionInfo(object):
     def __unicode__(self):
         entry = self.traceback[-1]
         loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
-        return unicode(loc)
+        return str(loc)
 
 
-class FormattedExcinfo(object):
+class FormattedExcinfo:
     """ presenting information about failing Functions and Generators. """
     # for traceback entries
     flow_marker = ">"
@@ -697,7 +694,7 @@ class ReprEntry(TerminalRepr):
             self.reprfileloc.toterminal(tw)
 
     def __str__(self):
-        return "%s\n%s\n%s" % ("\n".join(self.lines),
+        return "{}\n{}\n{}".format("\n".join(self.lines),
                                self.reprlocals,
                                self.reprfileloc)
 
diff --git a/python/py/py/_code/source.py b/python/py/py/_code/source.py
index 3a648e6357..807133727a 100644
--- a/python/py/py/_code/source.py
+++ b/python/py/py/_code/source.py
@@ -1,5 +1,3 @@
-from __future__ import generators
-
 from bisect import bisect_right
 import sys
 import inspect, tokenize
@@ -15,7 +13,7 @@ except ImportError:
     _ast = None
 
 
-class Source(object):
+class Source:
     """ a immutable object holding a source code fragment,
         possibly deindenting it.
     """
@@ -193,14 +191,13 @@ class Source(object):
             if flag & _AST_FLAG:
                 return co
             lines = [(x + "\n") for x in self.lines]
-            if sys.version_info[0] >= 3:
-                # XXX py3's inspect.getsourcefile() checks for a module
-                # and a pep302 __loader__ ... we don't have a module
-                # at code compile-time so we need to fake it here
-                m = ModuleType("_pycodecompile_pseudo_module")
-                py.std.inspect.modulesbyfile[filename] = None
-                py.std.sys.modules[None] = m
-                m.__loader__ = 1
+            # XXX py3's inspect.getsourcefile() checks for a module
+            # and a pep302 __loader__ ... we don't have a module
+            # at code compile-time so we need to fake it here
+            m = ModuleType("_pycodecompile_pseudo_module")
+            py.std.inspect.modulesbyfile[filename] = None
+            py.std.sys.modules[None] = m
+            m.__loader__ = 1
             py.std.linecache.cache[filename] = (1, None, lines, filename)
             return co
 
@@ -242,7 +239,7 @@ def getfslineno(obj):
         if fspath:
             try:
                 _, lineno = findsource(obj)
-            except IOError:
+            except OSError:
                 pass
     else:
         fspath = code.path
diff --git a/python/py/py/_error.py b/python/py/py/_error.py
index 550fb521a0..030a8c20fe 100644
--- a/python/py/py/_error.py
+++ b/python/py/py/_error.py
@@ -30,7 +30,7 @@ _winerrnomap = {
     5: errno.EACCES,  # anything better?
 }
 
-class ErrorMaker(object):
+class ErrorMaker:
     """ lazily provides Exception classes for each possible POSIX errno
         (as defined per the 'errno' module).  All such instances
         subclass EnvironmentError.
@@ -64,7 +64,7 @@ class ErrorMaker(object):
             return func(*args, **kwargs)
         except self.Error:
             raise
-        except (OSError, EnvironmentError):
+        except OSError:
             cls, value, tb = sys.exc_info()
             if not hasattr(value, 'errno'):
                 raise
@@ -81,7 +81,7 @@ class ErrorMaker(object):
                     cls = self._geterrnoclass(_winerrnomap[errno])
                 except KeyError:
                     raise value
-            raise cls("%s%r" % (func.__name__, args))
+            raise cls("{}{!r}".format(func.__name__, args))
             __tracebackhide__ = True
             
 
diff --git a/python/py/py/_iniconfig.py b/python/py/py/_iniconfig.py
index 92b50bd853..9c93b3ed82 100644
--- a/python/py/py/_iniconfig.py
+++ b/python/py/py/_iniconfig.py
@@ -17,7 +17,7 @@ class ParseError(Exception):
     def __str__(self):
         return "%s:%s: %s" %(self.path, self.lineno+1, self.msg)
 
-class SectionWrapper(object):
+class SectionWrapper:
     def __init__(self, config, name):
         self.config = config
         self.name = name
@@ -35,15 +35,14 @@ class SectionWrapper(object):
         section = self.config.sections.get(self.name, [])
         def lineof(key):
             return self.config.lineof(self.name, key)
-        for name in sorted(section, key=lineof):
-            yield name
+        yield from sorted(section, key=lineof)
 
     def items(self):
         for name in self:
             yield name, self[name]
 
 
-class IniConfig(object):
+class IniConfig:
     def __init__(self, path, data=None):
         self.path = str(path) # convenience
         if data is None:
@@ -98,7 +97,7 @@ class IniConfig(object):
                     self._raise(lineno, 'unexpected value continuation')
 
                 if last_data:
-                    data = '%s\n%s' % (last_data, data)
+                    data = '{}\n{}'.format(last_data, data)
                 result.append(last[:-1] + (data,))
         return result
 
diff --git a/python/py/py/_io/capture.py b/python/py/py/_io/capture.py
index bc157ed978..9ec9a8347b 100644
--- a/python/py/py/_io/capture.py
+++ b/python/py/py/_io/capture.py
@@ -8,21 +8,14 @@ try:
 except ImportError:
     from StringIO import StringIO
 
-if sys.version_info < (3,0):
-    class TextIO(StringIO):
-        def write(self, data):
-            if not isinstance(data, unicode):
-                data = unicode(data, getattr(self, '_encoding', 'UTF-8'), 'replace')
-            StringIO.write(self, data)
-else:
-    TextIO = StringIO
+TextIO = StringIO
 
 try:
     from io import BytesIO
 except ImportError:
     class BytesIO(StringIO):
         def write(self, data):
-            if isinstance(data, unicode):
+            if isinstance(data, str):
                 raise TypeError("not a byte value: %r" %(data,))
             StringIO.write(self, data)
 
@@ -105,24 +98,18 @@ def dupfile(f, mode=None, buffering=0, raising=False, encoding=None):
             raise
         return f
     newfd = os.dup(fd)
-    if sys.version_info >= (3,0):
-        if encoding is not None:
-            mode = mode.replace("b", "")
-            buffering = True
-        return os.fdopen(newfd, mode, buffering, encoding, closefd=True)
-    else:
-        f = os.fdopen(newfd, mode, buffering)
-        if encoding is not None:
-            return EncodedFile(f, encoding)
-        return f
+    if encoding is not None:
+        mode = mode.replace("b", "")
+        buffering = True
+    return os.fdopen(newfd, mode, buffering, encoding, closefd=True)
 
-class EncodedFile(object):
+class EncodedFile:
     def __init__(self, _stream, encoding):
         self._stream = _stream
         self.encoding = encoding
 
     def write(self, obj):
-        if isinstance(obj, unicode):
+        if isinstance(obj, str):
             obj = obj.encode(self.encoding)
         elif isinstance(obj, str):
             pass
@@ -137,7 +124,7 @@ class EncodedFile(object):
     def __getattr__(self, name):
         return getattr(self._stream, name)
 
-class Capture(object):
+class Capture:
     def call(cls, func, *args, **kwargs):
         """ return a (res, out, err) tuple where
             out and err represent the output/error output
@@ -350,7 +337,7 @@ class DontReadFromInput:
     hang indefinitely.
     """
     def read(self, *args):
-        raise IOError("reading from stdin while output is captured")
+        raise OSError("reading from stdin while output is captured")
     readline = read
     readlines = read
     __iter__ = read
diff --git a/python/py/py/_io/saferepr.py b/python/py/py/_io/saferepr.py
index 8518290efd..63ecc440fb 100644
--- a/python/py/py/_io/saferepr.py
+++ b/python/py/py/_io/saferepr.py
@@ -47,7 +47,7 @@ class SafeRepr(reprlib.Repr):
                 raise
             except:
                 exc_info = 'unknown'
-            return '<[%s("%s") raised in repr()] %s object at 0x%x>' % (
+            return '<[{}("{}") raised in repr()] {} object at 0x{:x}>'.format(
                 exc_name, exc_info, x.__class__.__name__, id(x))
         else:
             if len(s) > self.maxsize:
diff --git a/python/py/py/_io/terminalwriter.py b/python/py/py/_io/terminalwriter.py
index cef1ff5809..b990f42b42 100644
--- a/python/py/py/_io/terminalwriter.py
+++ b/python/py/py/_io/terminalwriter.py
@@ -116,7 +116,7 @@ def should_do_markup(file):
            and os.environ.get('TERM') != 'dumb' \
            and not (sys.platform.startswith('java') and os._name == 'nt')
 
-class TerminalWriter(object):
+class TerminalWriter:
     _esctable = dict(black=30, red=31, green=32, yellow=33,
                      blue=34, purple=35, cyan=36, white=37,
                      Black=40, Red=41, Green=42, Yellow=43,
@@ -174,7 +174,7 @@ class TerminalWriter(object):
             #         N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
             N = (fullwidth - len(title) - 2) // (2*len(sepchar))
             fill = sepchar * N
-            line = "%s %s %s" % (fill, title, fill)
+            line = "{} {} {}".format(fill, title, fill)
         else:
             # we want len(sepchar)*N <= fullwidth
             # i.e.    N <= fullwidth // len(sepchar)
@@ -245,7 +245,7 @@ class Win32ConsoleWriter(TerminalWriter):
             if oldcolors:
                 SetConsoleTextAttribute(handle, oldcolors)
 
-class WriteFile(object):
+class WriteFile:
     def __init__(self, writemethod, encoding=None):
         self.encoding = encoding
         self._writemethod = writemethod
diff --git a/python/py/py/_log/log.py b/python/py/py/_log/log.py
index ce47e8c754..004a0cb0f0 100644
--- a/python/py/py/_log/log.py
+++ b/python/py/py/_log/log.py
@@ -16,7 +16,7 @@ XXX implement this API: (maybe put it into slogger.py?)
 """
 import py, sys
 
-class Message(object):
+class Message:
     def __init__(self, keywords, args):
         self.keywords = keywords
         self.args = args
@@ -31,7 +31,7 @@ class Message(object):
         return self.prefix() + self.content()
 
 
-class Producer(object):
+class Producer:
     """ (deprecated) Log producer API which sends messages to be logged
         to a 'consumer' object, which then prints them to stdout,
         stderr, files, etc. Used extensively by PyPy-1.1.
@@ -92,15 +92,15 @@ class KeywordMapper:
         """ set a consumer for a set of keywords. """
         # normalize to tuples
         if isinstance(keywords, str):
-            keywords = tuple(filter(None, keywords.split()))
+            keywords = tuple([_f for _f in keywords.split() if _f])
         elif hasattr(keywords, '_keywords'):
             keywords = keywords._keywords
         elif not isinstance(keywords, tuple):
-            raise TypeError("key %r is not a string or tuple" % (keywords,))
+            raise TypeError("key {!r} is not a string or tuple".format(keywords))
         if consumer is not None and not py.builtin.callable(consumer):
             if not hasattr(consumer, 'write'):
                 raise TypeError(
-                    "%r should be None, callable or file-like" % (consumer,))
+                    "{!r} should be None, callable or file-like".format(consumer))
             consumer = File(consumer)
         self.keywords2consumer[keywords] = consumer
 
@@ -122,7 +122,7 @@ def getstate():
 # Consumers
 #
 
-class File(object):
+class File:
     """ log consumer wrapping a file(-like) object """
     def __init__(self, f):
         assert hasattr(f, 'write')
@@ -135,7 +135,7 @@ class File(object):
         if hasattr(self._file, 'flush'):
             self._file.flush()
 
-class Path(object):
+class Path:
     """ log consumer that opens and writes to a Path """
     def __init__(self, filename, append=False,
                  delayed_create=False, buffering=False):
diff --git a/python/py/py/_path/cacheutil.py b/python/py/py/_path/cacheutil.py
index 9922504750..26a519c93d 100644
--- a/python/py/py/_path/cacheutil.py
+++ b/python/py/py/_path/cacheutil.py
@@ -10,7 +10,7 @@ methods and allow configuration when instantiating the cache class.
 """
 from time import time as gettime
 
-class BasicCache(object):
+class BasicCache:
     def __init__(self, maxentries=128):
         self.maxentries = maxentries
         self.prunenum = int(maxentries - maxentries/8)
@@ -75,7 +75,7 @@ class BuildcostAccessCache(BasicCache):
         return WeightedCountingEntry(val, end-start)
 
 
-class WeightedCountingEntry(object):
+class WeightedCountingEntry:
     def __init__(self, value, oneweight):
         self._value = value
         self.weight = self._oneweight = oneweight
@@ -89,7 +89,7 @@ class AgingCache(BasicCache):
     """ This cache prunes out cache entries that are too old.
     """
     def __init__(self, maxentries=128, maxseconds=10.0):
-        super(AgingCache, self).__init__(maxentries)
+        super().__init__(maxentries)
         self.maxseconds = maxseconds
 
     def _getentry(self, key):
@@ -104,7 +104,7 @@ class AgingCache(BasicCache):
         entry = AgingEntry(val, gettime() + self.maxseconds)
         return entry
 
-class AgingEntry(object):
+class AgingEntry:
     def __init__(self, value, expirationtime):
         self.value = value
         self.weight = expirationtime
diff --git a/python/py/py/_path/common.py b/python/py/py/_path/common.py
index d407434cb2..509ddf6a32 100644
--- a/python/py/py/_path/common.py
+++ b/python/py/py/_path/common.py
@@ -59,7 +59,7 @@ class Checkers:
                         pass
             if meth is None:
                 raise TypeError(
-                    "no %r checker available for %r" % (name, self.path))
+                    "no {!r} checker available for {!r}".format(name, self.path))
             try:
                 if py.code.getrawcode(meth).co_argcount > 1:
                     if (not meth(value)) ^ invert:
@@ -84,7 +84,7 @@ class Checkers:
 class NeverRaised(Exception):
     pass
 
-class PathBase(object):
+class PathBase:
     """ shared implementation for filesystem path objects."""
     Checkers = Checkers
 
@@ -329,8 +329,7 @@ newline will be removed from the end of each line. """
 
             sort if True will sort entries within each directory level.
         """
-        for x in Visitor(fil, rec, ignore, bf, sort).gen(self):
-            yield x
+        yield from Visitor(fil, rec, ignore, bf, sort).gen(self)
 
     def _sortlist(self, res, sort):
         if sort:
diff --git a/python/py/py/_path/local.py b/python/py/py/_path/local.py
index d569404ec2..eef0cbe40b 100644
--- a/python/py/py/_path/local.py
+++ b/python/py/py/_path/local.py
@@ -1,7 +1,6 @@
 """
 local path implementation.
 """
-from __future__ import with_statement
 
 from contextlib import contextmanager
 import sys, os, re, atexit, io
@@ -12,13 +11,10 @@ from stat import S_ISLNK, S_ISDIR, S_ISREG
 
 from os.path import abspath, normpath, isabs, exists, isdir, isfile, islink, dirname
 
-if sys.version_info > (3,0):
-    def map_as_list(func, iter):
-        return list(map(func, iter))
-else:
-    map_as_list = map
+def map_as_list(func, iter):
+    return list(map(func, iter))
 
-class Stat(object):
+class Stat:
     def __getattr__(self, name):
         return getattr(self._osstatresult, "st_" + name)
 
@@ -279,7 +275,7 @@ class LocalPath(FSBase):
         res = []
         parts = self.strpath.split(self.sep)
 
-        args = filter(None, spec.split(',') )
+        args = [_f for _f in spec.split(',') if _f]
         append = res.append
         for name in args:
             if name == 'drive':
@@ -312,7 +308,7 @@ class LocalPath(FSBase):
             if args:
                 path = path.join(*args)
             return path
-        return super(LocalPath, self).dirpath(*args, **kwargs)
+        return super().dirpath(*args, **kwargs)
 
     def join(self, *args, **kwargs):
         """ return a new path by appending all 'args' as path
@@ -368,7 +364,7 @@ class LocalPath(FSBase):
                 return not kw["dir"] ^ isdir(self.strpath)
             if "file" in kw:
                 return not kw["file"] ^ isfile(self.strpath)
-        return super(LocalPath, self).check(**kw)
+        return super().check(**kw)
 
     _patternchars = set("*?[" + os.path.sep)
     def listdir(self, fil=None, sort=None):
@@ -586,7 +582,7 @@ class LocalPath(FSBase):
             if rec is True perform recursively.
         """
         if not isinstance(mode, int):
-            raise TypeError("mode %r must be an integer" % (mode,))
+            raise TypeError("mode {!r} must be an integer".format(mode))
         if rec:
             for x in self.visit(rec=rec):
                 py.error.checked_call(os.chmod, str(x), mode)
diff --git a/python/py/py/_path/svnurl.py b/python/py/py/_path/svnurl.py
index 78d71317ac..e6dc33731b 100644
--- a/python/py/py/_path/svnurl.py
+++ b/python/py/py/_path/svnurl.py
@@ -4,6 +4,7 @@ command 'svn'. This modules aims to work with svn 1.3 and higher
 but might also interact well with earlier versions.
 """
 
+from __future__ import print_function
 import os, sys, time, re
 import py
 from py import path, process
@@ -37,7 +38,7 @@ class SvnCommandPath(svncommon.SvnPathBase):
         if self.rev == -1:
             return 'svnurl(%r)' % self.strpath
         else:
-            return 'svnurl(%r, %r)' % (self.strpath, self.rev)
+            return 'svnurl({!r}, {!r})'.format(self.strpath, self.rev)
 
     def _svnwithrev(self, cmd, *args):
         """ execute an svn command, append our own url and revision """
@@ -56,7 +57,7 @@ class SvnCommandPath(svncommon.SvnPathBase):
         # fixing the locale because we can't otherwise parse
         string = " ".join(l)
         if DEBUG:
-            print("execing %s" % string)
+            print(("execing %s" % string))
         out = self._svncmdexecauth(string)
         return out
 
@@ -98,13 +99,13 @@ class SvnCommandPath(svncommon.SvnPathBase):
     def open(self, mode='r'):
         """ return an opened file with the given mode. """
         if mode not in ("r", "rU",):
-            raise ValueError("mode %r not supported" % (mode,))
+            raise ValueError("mode {!r} not supported".format(mode))
         assert self.check(file=1) # svn cat returns an empty file otherwise
         if self.rev is None:
-            return self._svnpopenauth('svn cat "%s"' % (
-                                      self._escape(self.strpath), ))
+            return self._svnpopenauth('svn cat "{}"'.format(
+                                      self._escape(self.strpath)))
         else:
-            return self._svnpopenauth('svn cat -r %s "%s"' % (
+            return self._svnpopenauth('svn cat -r {} "{}"'.format(
                                       self.rev, self._escape(self.strpath)))
 
     def dirpath(self, *args, **kwargs):
@@ -162,11 +163,11 @@ checkin message msg."""
             py.path.local instance
         """
         topath = py.path.local(topath)
-        args = ['"%s"' % (self._escape(self),),
-                '"%s"' % (self._escape(topath),)]
+        args = ['"{}"'.format(self._escape(self)),
+                '"{}"'.format(self._escape(topath))]
         if self.rev is not None:
             args = ['-r', str(self.rev)] + args
-        self._svncmdexecauth('svn export %s' % (' '.join(args),))
+        self._svncmdexecauth('svn export {}'.format(' '.join(args)))
         return topath
 
     def ensure(self, *args, **kwargs):
@@ -192,7 +193,7 @@ checkin message msg."""
         tempdir = py.path.local.mkdtemp()
         try:
             tempdir.ensure(tocreate, dir=dir)
-            cmd = 'svn import -m "%s" "%s" "%s"' % (
+            cmd = 'svn import -m "{}" "{}" "{}"'.format(
                     "ensure %s" % self._escape(tocreate),
                     self._escape(tempdir.join(basename)),
                     x.join(basename)._encodedurl())
@@ -293,14 +294,14 @@ if verbose is True, then the LogEntry instances also know which files changed.
         if rev_start == "HEAD" and rev_end == 1:
             rev_opt = ""
         else:
-            rev_opt = "-r %s:%s" % (rev_start, rev_end)
+            rev_opt = "-r {}:{}".format(rev_start, rev_end)
         verbose_opt = verbose and "-v" or ""
         xmlpipe =  self._svnpopenauth('svn log --xml %s %s "%s"' %
                                       (rev_opt, verbose_opt, self.strpath))
         from xml.dom import minidom
         tree = minidom.parse(xmlpipe)
         result = []
-        for logentry in filter(None, tree.firstChild.childNodes):
+        for logentry in [_f for _f in tree.firstChild.childNodes if _f]:
             if logentry.nodeType == logentry.ELEMENT_NODE:
                 result.append(svncommon.LogEntry(logentry))
         return result
@@ -315,7 +316,7 @@ class InfoSvnCommand:
     # locked, see 'svn help ls'
     lspattern = re.compile(
         r'^ *(?P\d+) +(?P.+?) +(0? *(?P\d+))? '
-            '*(?P\w+ +\d{2} +[\d:]+) +(?P.*)$')
+            r'*(?P\w+ +\d{2} +[\d:]+) +(?P.*)$')
     def __init__(self, line):
         # this is a typical line from 'svn ls http://...'
         #_    1127      jum        0 Jul 13 15:28 branch/
diff --git a/python/py/py/_path/svnwc.py b/python/py/py/_path/svnwc.py
index 00d3b4bbaf..66d9110f2d 100644
--- a/python/py/py/_path/svnwc.py
+++ b/python/py/py/_path/svnwc.py
@@ -115,7 +115,7 @@ def checkbadchars(url):
         # only check for bad chars in the non-protocol parts
         if (_check_for_bad_chars(host, ALLOWED_CHARS_HOST) \
             or _check_for_bad_chars(uripath, ALLOWED_CHARS)):
-            raise ValueError("bad char in %r" % (url, ))
+            raise ValueError("bad char in {!r}".format(url))
 
 
 #_______________________________________________________________
@@ -270,7 +270,7 @@ class SvnPathBase(common.PathBase):
     #        except (IOError, process.cmdexec.Error):
     #            break
     #    if rev is None:
-    #        raise IOError, "could not determine newest repo revision for %s" % self
+    #        raise IOError("could not determine newest repo revision for %s" % self)
     #    return rev
 
     class Checkers(common.Checkers):
@@ -327,7 +327,7 @@ def fixlocale():
     return ''
 
 # some nasty chunk of code to solve path and url conversion and quoting issues
-ILLEGAL_CHARS = '* | \ / : < > ? \t \n \x0b \x0c \r'.split(' ')
+ILLEGAL_CHARS = '* | \\ / : < > ? \t \n \x0b \x0c \r'.split(' ')
 if os.sep in ILLEGAL_CHARS:
     ILLEGAL_CHARS.remove(os.sep)
 ISWINDOWS = sys.platform == 'win32'
@@ -341,15 +341,15 @@ def _check_path(path):
             raise ValueError('path may not contain a colon (:)')
     for char in sp:
         if char not in string.printable or char in illegal:
-            raise ValueError('illegal character %r in path' % (char,))
+            raise ValueError('illegal character {!r} in path'.format(char))
 
 def path_to_fspath(path, addat=True):
     _check_path(path)
     sp = path.strpath
     if addat and path.rev != -1:
-        sp = '%s@%s' % (sp, path.rev)
+        sp = '{}@{}'.format(sp, path.rev)
     elif addat:
-        sp = '%s@HEAD' % (sp,)
+        sp = '{}@HEAD'.format(sp)
     return sp
 
 def url_from_path(path):
@@ -359,19 +359,19 @@ def url_from_path(path):
         match = _reg_allow_disk.match(fspath)
         fspath = fspath.replace('\\', '/')
         if match.group(1):
-            fspath = '/%s%s' % (match.group(1).replace('\\', '/'),
+            fspath = '/{}{}'.format(match.group(1).replace('\\', '/'),
                                 quote(fspath[len(match.group(1)):]))
         else:
             fspath = quote(fspath)
     else:
         fspath = quote(fspath)
     if path.rev != -1:
-        fspath = '%s@%s' % (fspath, path.rev)
+        fspath = '{}@{}'.format(fspath, path.rev)
     else:
-        fspath = '%s@HEAD' % (fspath,)
-    return 'file://%s' % (fspath,)
+        fspath = '{}@HEAD'.format(fspath)
+    return 'file://{}'.format(fspath)
 
-class SvnAuth(object):
+class SvnAuth:
     """ container for auth information for Subversion """
     def __init__(self, username, password, cache_auth=True, interactive=True):
         self.username = username
@@ -384,9 +384,9 @@ class SvnAuth(object):
         passwd = self.password.replace('"', '\\"')
         ret = []
         if uname:
-            ret.append('--username="%s"' % (uname,))
+            ret.append('--username="{}"'.format(uname))
         if passwd:
-            ret.append('--password="%s"' % (passwd,))
+            ret.append('--password="{}"'.format(passwd))
         if not self.cache_auth:
             ret.append('--no-auth-cache')
         if not self.interactive:
@@ -413,7 +413,7 @@ class SvnWCCommandPath(common.PathBase):
             wcpath = wcpath.localpath
         if _check_for_bad_chars(str(wcpath),
                                           ALLOWED_CHARS):
-            raise ValueError("bad char in wcpath %s" % (wcpath, ))
+            raise ValueError("bad char in wcpath {}".format(wcpath))
         self.localpath = py.path.local(wcpath)
         self.auth = auth
         return self
@@ -639,11 +639,11 @@ class SvnWCCommandPath(common.PathBase):
             updates = ''
 
         try:
-            cmd = 'status -v --xml --no-ignore %s %s %s' % (
+            cmd = 'status -v --xml --no-ignore {} {} {}'.format(
                     updates, rec, externals)
             out = self._authsvn(cmd)
         except py.process.cmdexec.Error:
-            cmd = 'status -v --no-ignore %s %s %s' % (
+            cmd = 'status -v --no-ignore {} {} {}'.format(
                     updates, rec, externals)
             out = self._authsvn(cmd)
             rootstatus = WCStatus(self).fromstring(out, self)
@@ -683,7 +683,7 @@ class SvnWCCommandPath(common.PathBase):
     def commit(self, msg='', rec=1):
         """ commit with support for non-recursive commits """
         # XXX i guess escaping should be done better here?!?
-        cmd = 'commit -m "%s" --force-log' % (msg.replace('"', '\\"'),)
+        cmd = 'commit -m "{}" --force-log'.format(msg.replace('"', '\\"'))
         if not rec:
             cmd += ' -N'
         out = self._authsvn(cmd)
@@ -788,7 +788,7 @@ recursively. """
             if py.std.sys.platform != 'win32':
                 if info.path != self.localpath:
                     raise py.error.ENOENT(self, "not a versioned resource:" +
-                            " %s != %s" % (info.path, self.localpath))
+                            " {} != {}".format(info.path, self.localpath))
             cache.info[self] = info
         return info
 
@@ -850,7 +850,7 @@ if verbose is True, then the LogEntry instances also know which files changed.
         if rev_start == "HEAD" and rev_end == 1:
                 rev_opt = ""
         else:
-            rev_opt = "-r %s:%s" % (rev_start, rev_end)
+            rev_opt = "-r {}:{}".format(rev_start, rev_end)
         verbose_opt = verbose and "-v" or ""
         locale_env = fixlocale()
         # some blather on stderr
@@ -859,7 +859,7 @@ if verbose is True, then the LogEntry instances also know which files changed.
         #                                   'svn log --xml %s %s %s "%s"' % (
         #                                    rev_opt, verbose_opt, auth_opt,
         #                                    self.strpath))
-        cmd = locale_env + 'svn log --xml %s %s %s "%s"' % (
+        cmd = locale_env + 'svn log --xml {} {} {} "{}"'.format(
             rev_opt, verbose_opt, auth_opt, self.strpath)
 
         popen = subprocess.Popen(cmd,
@@ -875,7 +875,7 @@ if verbose is True, then the LogEntry instances also know which files changed.
         except ExpatError:
             raise ValueError('no such revision')
         result = []
-        for logentry in filter(None, tree.firstChild.childNodes):
+        for logentry in [_f for _f in tree.firstChild.childNodes if _f]:
             if logentry.nodeType == logentry.ELEMENT_NODE:
                 result.append(LogEntry(logentry))
         return result
@@ -913,7 +913,7 @@ class WCStatus:
             if name not in kw or kw[name]:
                 for path in getattr(self, name):
                     d[path] = 1
-        l = d.keys()
+        l = list(d.keys())
         if sort:
             l.sort()
         return l
@@ -1151,7 +1151,7 @@ class InfoSvnWCCommand:
             self.url = d['url']
         except KeyError:
             raise  ValueError("Not a versioned resource")
-            #raise ValueError, "Not a versioned resource %r" % path
+            #raise ValueError("Not a versioned resource %r" % path)
         self.kind = d['nodekind'] == 'directory' and 'dir' or d['nodekind']
         try:
             self.rev = int(d['revision'])
@@ -1215,7 +1215,7 @@ def importxml(cache=[]):
 class LogEntry:
     def __init__(self, logentry):
         self.rev = int(logentry.getAttribute('revision'))
-        for lpart in filter(None, logentry.childNodes):
+        for lpart in [_f for _f in logentry.childNodes if _f]:
             if lpart.nodeType == lpart.ELEMENT_NODE:
                 if lpart.nodeName == 'author':
                     self.author = lpart.firstChild.nodeValue
@@ -1230,7 +1230,7 @@ class LogEntry:
                     self.date = parse_apr_time(timestr)
                 elif lpart.nodeName == 'paths':
                     self.strpaths = []
-                    for ppart in filter(None, lpart.childNodes):
+                    for ppart in [_f for _f in lpart.childNodes if _f]:
                         if ppart.nodeType == ppart.ELEMENT_NODE:
                             self.strpaths.append(PathEntry(ppart))
     def __repr__(self):
diff --git a/python/py/py/_process/cmdexec.py b/python/py/py/_process/cmdexec.py
index f83a249402..31296d94ca 100644
--- a/python/py/py/_process/cmdexec.py
+++ b/python/py/py/_process/cmdexec.py
@@ -21,8 +21,8 @@ def cmdexec(cmd):
             default_encoding = sys.getdefaultencoding() # jython may not have it
         except AttributeError:
             default_encoding = sys.stdout.encoding or 'UTF-8'
-        out = unicode(out, process.stdout.encoding or default_encoding)
-        err = unicode(err, process.stderr.encoding or default_encoding)
+        out = str(out, process.stdout.encoding or default_encoding)
+        err = str(err, process.stderr.encoding or default_encoding)
     status = process.poll()
     if status:
         raise ExecutionFailed(status, status, cmd, out, err)
diff --git a/python/py/py/_process/forkedfunc.py b/python/py/py/_process/forkedfunc.py
index 1c28530688..f334ea6004 100644
--- a/python/py/py/_process/forkedfunc.py
+++ b/python/py/py/_process/forkedfunc.py
@@ -1,4 +1,3 @@
-
 """
     ForkedFunc provides a way to run a function in a forked process
     and get at its return value, stdout and stderr output as well
@@ -111,7 +110,7 @@ class ForkedFunc:
             self._removetemp()
 
 
-class Result(object):
+class Result:
     def __init__(self, exitstatus, signal, retval, stdout, stderr):
         self.exitstatus = exitstatus
         self.signal = signal
diff --git a/python/py/py/_std.py b/python/py/py/_std.py
index 97a9853323..0a91d91cb5 100644
--- a/python/py/py/_std.py
+++ b/python/py/py/_std.py
@@ -1,6 +1,6 @@
 import sys
 
-class Std(object):
+class Std:
     """ makes top-level python modules available as an attribute,
         importing them on first access.
     """
diff --git a/python/py/py/_xmlgen.py b/python/py/py/_xmlgen.py
index 2ffcaa14b8..6e4150d92d 100644
--- a/python/py/py/_xmlgen.py
+++ b/python/py/py/_xmlgen.py
@@ -6,17 +6,12 @@ by using simple python objects.
 """
 import sys, re
 
-if sys.version_info >= (3,0):
-    def u(s):
-        return s
-    def unicode(x, errors=None):
-        if hasattr(x, '__unicode__'):
-            return x.__unicode__()
-        return str(x)
-else:
-    def u(s):
-        return unicode(s)
-    unicode = unicode
+def u(s):
+    return s
+def str(x, errors=None):
+    if hasattr(x, '__unicode__'):
+        return x.__unicode__()
+    return str(x)
 
 
 class NamespaceMetaclass(type):
@@ -36,19 +31,19 @@ class NamespaceMetaclass(type):
         return cls
 
 class Tag(list):
-    class Attr(object):
+    class Attr:
         def __init__(self, **kwargs):
             self.__dict__.update(kwargs)
 
     def __init__(self, *args, **kwargs):
-        super(Tag, self).__init__(args)
+        super().__init__(args)
         self.attr = self.Attr(**kwargs)
 
     def __unicode__(self):
-        return self.unicode(indent=0)
+        return self.str(indent=0)
     __str__ = __unicode__
 
-    def unicode(self, indent=2):
+    def str(self, indent=2):
         l = []
         SimpleUnicodeVisitor(l.append, indent).visit(self)
         return u("").join(l)
@@ -64,7 +59,7 @@ Namespace = NamespaceMetaclass('Namespace', (object, ), {
 })
 
 class HtmlTag(Tag):
-    def unicode(self, indent=2):
+    def str(self, indent=2):
         l = []
         HtmlVisitor(l.append, indent, shortempty=False).visit(self)
         return u("").join(l)
@@ -73,7 +68,7 @@ class HtmlTag(Tag):
 class html(Namespace):
     __tagclass__ = HtmlTag
     __stickyname__ = True
-    __tagspec__ = dict([(x,1) for x in (
+    __tagspec__ = {x:1 for x in (
         'a,abbr,acronym,address,applet,area,b,bdo,big,blink,'
         'blockquote,body,br,button,caption,center,cite,code,col,'
         'colgroup,comment,dd,del,dfn,dir,div,dl,dt,em,embed,'
@@ -84,22 +79,22 @@ class html(Namespace):
         'select,small,span,strike,strong,style,sub,sup,table,'
         'tbody,td,textarea,tfoot,th,thead,title,tr,tt,u,ul,xmp,'
         'base,basefont,frame,hr,isindex,param,samp,var'
-    ).split(',') if x])
+    ).split(',') if x}
 
-    class Style(object):
+    class Style:
         def __init__(self, **kw):
             for x, y in kw.items():
                 x = x.replace('_', '-')
                 setattr(self, x, y)
 
 
-class raw(object):
+class raw:
     """just a box that can contain a unicode string that will be
     included directly in the output"""
     def __init__(self, uniobj):
         self.uniobj = uniobj
 
-class SimpleUnicodeVisitor(object):
+class SimpleUnicodeVisitor:
     """ recursive visitor to write unicode. """
     def __init__(self, write, indent=0, curindent=0, shortempty=True):
         self.write = write
@@ -129,7 +124,7 @@ class SimpleUnicodeVisitor(object):
     # to avoid clashes with the tag name object
     def __object(self, obj):
         #self.write(obj)
-        self.write(escape(unicode(obj)))
+        self.write(escape(str(obj)))
 
     def raw(self, obj):
         self.write(obj.uniobj)
@@ -186,8 +181,8 @@ class SimpleUnicodeVisitor(object):
             if isinstance(value, raw):
                 insert = value.uniobj
             else:
-                insert = escape(unicode(value))
-            return ' %s="%s"' % (name, insert)
+                insert = escape(str(value))
+            return ' {}="{}"'.format(name, insert)
 
     def getstyle(self, tag):
         """ return attribute list suitable for styling. """
@@ -209,20 +204,20 @@ class SimpleUnicodeVisitor(object):
 
 class HtmlVisitor(SimpleUnicodeVisitor):
 
-    single = dict([(x, 1) for x in
+    single = {x: 1 for x in
                 ('br,img,area,param,col,hr,meta,link,base,'
-                    'input,frame').split(',')])
-    inline = dict([(x, 1) for x in
+                    'input,frame').split(',')}
+    inline = {x: 1 for x in
                 ('a abbr acronym b basefont bdo big br cite code dfn em font '
                  'i img input kbd label q s samp select small span strike '
-                 'strong sub sup textarea tt u var'.split(' '))])
+                 'strong sub sup textarea tt u var'.split(' '))}
 
     def repr_attribute(self, attrs, name):
         if name == 'class_':
             value = getattr(attrs, name)
             if value is None:
                 return
-        return super(HtmlVisitor, self).repr_attribute(attrs, name)
+        return super().repr_attribute(attrs, name)
 
     def _issingleton(self, tagname):
         return tagname in self.single
@@ -237,7 +232,7 @@ class _escape:
             u('"') : u('"'), u('<') : u('<'), u('>') : u('>'),
             u('&') : u('&'), u("'") : u('''),
             }
-        self.charef_rex = re.compile(u("|").join(self.escape.keys()))
+        self.charef_rex = re.compile(u("|").join(list(self.escape.keys())))
 
     def _replacer(self, match):
         return self.escape[match.group(0)]
@@ -245,9 +240,9 @@ class _escape:
     def __call__(self, ustring):
         """ xml-escape the given unicode string. """
         try:
-            ustring = unicode(ustring)
+            ustring = str(ustring)
         except UnicodeDecodeError:
-            ustring = unicode(ustring, 'utf-8', errors='replace')
+            ustring = str(ustring, 'utf-8', errors='replace')
         return self.charef_rex.sub(self._replacer, ustring)
 
 escape = _escape()
diff --git a/python/pyasn1-modules/pyasn1_modules/pem.py b/python/pyasn1-modules/pyasn1_modules/pem.py
index d8d815873e..80da400235 100644
--- a/python/pyasn1-modules/pyasn1_modules/pem.py
+++ b/python/pyasn1-modules/pyasn1_modules/pem.py
@@ -5,10 +5,8 @@ stSpam, stHam, stDump = 0, 1, 2
 # The markers parameters is in form ('start1', 'stop1'), ('start2', 'stop2')...
 # Return is (marker-index, substrate)
 def readPemBlocksFromFile(fileObj, *markers):
-    startMarkers = dict(map(lambda x: (x[1],x[0]),
-                            enumerate(map(lambda x: x[0], markers))))
-    stopMarkers = dict(map(lambda x: (x[1],x[0]),
-                           enumerate(map(lambda x: x[1], markers))))
+    startMarkers = dict([(x[1],x[0]) for x in enumerate([x[0] for x in markers])])
+    stopMarkers = dict([(x[1],x[0]) for x in enumerate([x[1] for x in markers])])
     idx = -1; substrate = ''
     state = stSpam
     while 1:
@@ -31,7 +29,7 @@ def readPemBlocksFromFile(fileObj, *markers):
             if sys.version_info[0] <= 2:
                 substrate = ''.join([ base64.b64decode(x) for x in certLines ])
             else:
-                substrate = ''.encode().join([ base64.b64decode(x.encode()) for x in certLines ])
+                substrate = b''.join([ base64.b64decode(x.encode()) for x in certLines ])
             break
     return idx, substrate
 
@@ -46,6 +44,6 @@ def readBase64FromFile(fileObj):
     if sys.version_info[0] <= 2:
         return ''.join([ base64.b64decode(x) for x in fileObj.readlines() ])
     else:
-        return ''.encode().join(
+        return b''.join(
             [ base64.b64decode(x.encode()) for x in fileObj.readlines() ]
         )
diff --git a/python/pyasn1-modules/setup.py b/python/pyasn1-modules/setup.py
index b7530caa8b..3ce106b000 100644
--- a/python/pyasn1-modules/setup.py
+++ b/python/pyasn1-modules/setup.py
@@ -6,6 +6,7 @@
    data structures (X.509, PKCS etc.).
 """
 
+from __future__ import print_function
 classifiers = """\
 Development Status :: 5 - Production/Stable
 Environment :: Console
diff --git a/python/pyasn1-modules/tools/cmpdump.py b/python/pyasn1-modules/tools/cmpdump.py
index 74c4f77a4e..58806ee0e5 100755
--- a/python/pyasn1-modules/tools/cmpdump.py
+++ b/python/pyasn1-modules/tools/cmpdump.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 # Read ASN.1/PEM CMP message on stdin, parse into
 # plain text, then build substrate from it
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc4210, pem
 from pyasn1 import debug
@@ -9,8 +10,8 @@ import sys
 if len(sys.argv) == 2 and sys.argv[1] == '-d':
     debug.setLogger(debug.Debug('all'))
 elif len(sys.argv) != 1:
-    print("""Usage:
-$ cat cmp.pem | %s [-d]""" % sys.argv[0])
+    print(("""Usage:
+$ cat cmp.pem | %s [-d]""" % sys.argv[0]))
     sys.exit(-1)
     
 pkiMessage = rfc4210.PKIMessage()
@@ -21,7 +22,7 @@ if not substrate:
         
 pkiMsg, rest = decoder.decode(substrate, asn1Spec=pkiMessage)
 
-print(pkiMsg.prettyPrint())
+print((pkiMsg.prettyPrint()))
 
 assert encoder.encode(pkiMsg, defMode=False) == substrate or \
        encoder.encode(pkiMsg, defMode=True) == substrate, \
diff --git a/python/pyasn1-modules/tools/crldump.py b/python/pyasn1-modules/tools/crldump.py
index d4b0a547c6..6f61dcc119 100755
--- a/python/pyasn1-modules/tools/crldump.py
+++ b/python/pyasn1-modules/tools/crldump.py
@@ -4,13 +4,14 @@
 # original wire format.
 # CRL can be generated with "openssl openssl ca -gencrl ..." commands.
 #
+from __future__ import print_function
 from pyasn1_modules import rfc2459, pem
 from pyasn1.codec.der import encoder, decoder
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat crl.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat crl.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 asn1Spec = rfc2459.CertificateList()
@@ -27,7 +28,7 @@ while 1:
 
     if rest: substrate = substrate[:-len(rest)]
         
-    print(key.prettyPrint())
+    print((key.prettyPrint()))
 
     assert encoder.encode(key, defMode=False) == substrate or \
            encoder.encode(key, defMode=True) == substrate, \
@@ -35,4 +36,4 @@ while 1:
         
     cnt = cnt + 1
  
-print('*** %s CRL(s) re/serialized' % cnt)
+print(('*** %s CRL(s) re/serialized' % cnt))
diff --git a/python/pyasn1-modules/tools/crmfdump.py b/python/pyasn1-modules/tools/crmfdump.py
index 22bfc9d950..764b897440 100755
--- a/python/pyasn1-modules/tools/crmfdump.py
+++ b/python/pyasn1-modules/tools/crmfdump.py
@@ -1,13 +1,14 @@
 #!/usr/bin/python
 # Read ASN.1/PEM X.509 CRMF request on stdin, parse into
 # plain text, then build substrate from it
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2511, pem
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat crmf.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat crmf.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 certReq = rfc2511.CertReqMessages()
@@ -18,7 +19,7 @@ if not substrate:
         
 cr, rest = decoder.decode(substrate, asn1Spec=certReq)
 
-print(cr.prettyPrint())
+print((cr.prettyPrint()))
 
 assert encoder.encode(cr, defMode=False) == substrate or \
        encoder.encode(cr, defMode=True) == substrate, \
diff --git a/python/pyasn1-modules/tools/ocspclient.py b/python/pyasn1-modules/tools/ocspclient.py
index b2d1dfc54f..d125cbad0a 100755
--- a/python/pyasn1-modules/tools/ocspclient.py
+++ b/python/pyasn1-modules/tools/ocspclient.py
@@ -1,11 +1,12 @@
 #!/usr/bin/python
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2560, rfc2459, pem
 from pyasn1.type import univ
 import sys, hashlib
 try:
-  import urllib2
+  import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 except ImportError:
   import urllib.request as urllib2
 
@@ -33,7 +34,7 @@ def mkOcspRequest(issuerCert, userCert):
     userTbsCertificate = userCert.getComponentByName('tbsCertificate')
     userIssuer = userTbsCertificate.getComponentByName('issuer')
 
-    assert issuerSubject == userIssuer, '%s\n%s' % (
+    assert issuerSubject == userIssuer, '{}\n{}'.format(
         issuerSubject.prettyPrint(), userIssuer.prettyPrint()
         )
 
@@ -97,8 +98,8 @@ def parseOcspResponse(ocspResponse):
         )
 
 if len(sys.argv) != 2:
-    print("""Usage:
-$ cat CACertificate.pem userCertificate.pem | %s """ % sys.argv[0])
+    print(("""Usage:
+$ cat CACertificate.pem userCertificate.pem | %s """ % sys.argv[0]))
     sys.exit(-1)
 else:
     ocspUrl = sys.argv[1]
@@ -125,12 +126,12 @@ ocspReq = mkOcspRequest(issuerCert, userCert)
 # Use HTTP POST to get response (see Appendix A of RFC 2560)
 # In case you need proxies, set the http_proxy env variable
 
-httpReq = urllib2.Request(
+httpReq = six.moves.urllib.request.Request(
     ocspUrl,
     encoder.encode(ocspReq),
     { 'Content-Type': 'application/ocsp-request' }
     )
-httpRsp = urllib2.urlopen(httpReq).read()
+httpRsp = six.moves.urllib.request.urlopen(httpReq).read()
 
 # Process OCSP response
     
@@ -138,8 +139,8 @@ ocspRsp, _ = decoder.decode(httpRsp, asn1Spec=rfc2560.OCSPResponse())
 
 producedAt, certId, certStatus, thisUpdate = parseOcspResponse(ocspRsp)
 
-print('Certificate ID %s is %s at %s till %s\n' % (
+print(('Certificate ID {} is {} at {} till {}\n'.format(
        certId.getComponentByName('serialNumber'),
        certStatus,
        producedAt,
-       thisUpdate))
+       thisUpdate)))
diff --git a/python/pyasn1-modules/tools/ocspreqdump.py b/python/pyasn1-modules/tools/ocspreqdump.py
index 3a03115ea4..a7e19ae86a 100755
--- a/python/pyasn1-modules/tools/ocspreqdump.py
+++ b/python/pyasn1-modules/tools/ocspreqdump.py
@@ -3,13 +3,14 @@
 # Read ASN.1/PEM X.509 CRMF request on stdin, parse into
 # plain text, then build substrate from it
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2560, pem
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat ocsp-request.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat ocsp-request.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 ocspReq = rfc2560.OCSPRequest()
@@ -20,7 +21,7 @@ if not substrate:
         
 cr, rest = decoder.decode(substrate, asn1Spec=ocspReq)
 
-print(cr.prettyPrint())
+print((cr.prettyPrint()))
 
 assert encoder.encode(cr, defMode=False) == substrate or \
        encoder.encode(cr, defMode=True) == substrate, \
diff --git a/python/pyasn1-modules/tools/ocsprspdump.py b/python/pyasn1-modules/tools/ocsprspdump.py
index 9e49ce038d..562d563705 100755
--- a/python/pyasn1-modules/tools/ocsprspdump.py
+++ b/python/pyasn1-modules/tools/ocsprspdump.py
@@ -3,13 +3,14 @@
 # Read ASN.1/PEM OCSP response on stdin, parse into
 # plain text, then build substrate from it
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2560, pem
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat ocsp-response.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat ocsp-response.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 ocspReq = rfc2560.OCSPResponse()
@@ -20,7 +21,7 @@ if not substrate:
         
 cr, rest = decoder.decode(substrate, asn1Spec=ocspReq)
 
-print(cr.prettyPrint())
+print((cr.prettyPrint()))
 
 assert encoder.encode(cr, defMode=False) == substrate or \
        encoder.encode(cr, defMode=True) == substrate, \
diff --git a/python/pyasn1-modules/tools/ocspserver.py b/python/pyasn1-modules/tools/ocspserver.py
index 2d12d53998..e862720f67 100755
--- a/python/pyasn1-modules/tools/ocspserver.py
+++ b/python/pyasn1-modules/tools/ocspserver.py
@@ -1,11 +1,12 @@
 #!/usr/bin/python
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2560, rfc2459, pem
 from pyasn1.type import univ
 import sys, hashlib
 try:
-    import urllib2
+    import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 except ImportError:
     import urllib.request as urllib2
 
@@ -33,7 +34,7 @@ def mkOcspRequest(issuerCert, userCert):
     userTbsCertificate = userCert.getComponentByName('tbsCertificate')
     userIssuer = userTbsCertificate.getComponentByName('issuer')
 
-    assert issuerSubject == userIssuer, '%s\n%s' % (
+    assert issuerSubject == userIssuer, '{}\n{}'.format(
         issuerSubject.prettyPrint(), userIssuer.prettyPrint()
         )
 
@@ -98,8 +99,8 @@ def parseOcspRequest(ocspRequest):
         )
 
 if len(sys.argv) != 2:
-    print("""Usage:
-$ cat CACertificate.pem userCertificate.pem | %s """ % sys.argv[0])
+    print(("""Usage:
+$ cat CACertificate.pem userCertificate.pem | %s """ % sys.argv[0]))
     sys.exit(-1)
 else:
     ocspUrl = sys.argv[1]
@@ -122,12 +123,12 @@ ocspReq = mkOcspRequest(issuerCert, userCert)
 # Use HTTP POST to get response (see Appendix A of RFC 2560)
 # In case you need proxies, set the http_proxy env variable
 
-httpReq = urllib2.Request(
+httpReq = six.moves.urllib.request.Request(
     ocspUrl,
     encoder.encode(ocspReq),
     { 'Content-Type': 'application/ocsp-request' }
     )
-httpRsp = urllib2.urlopen(httpReq).read()
+httpRsp = six.moves.urllib.request.urlopen(httpReq).read()
 
 # Process OCSP response
     
@@ -135,9 +136,9 @@ ocspRsp, _ = decoder.decode(httpRsp, asn1Spec=rfc2560.OCSPResponse())
 
 producedAt, certId, certStatus, thisUpdate = parseOcspResponse(ocspRsp)
 
-print('Certificate ID %s is %s at %s till %s\n' % (
+print(('Certificate ID {} is {} at {} till {}\n'.format(
     certId.getComponentByName('serialNumber'),
     certStatus,
     producedAt,
     thisUpdate
-    ))
+    )))
diff --git a/python/pyasn1-modules/tools/pkcs10dump.py b/python/pyasn1-modules/tools/pkcs10dump.py
index ea979c0cf5..976d5c0e76 100755
--- a/python/pyasn1-modules/tools/pkcs10dump.py
+++ b/python/pyasn1-modules/tools/pkcs10dump.py
@@ -3,13 +3,14 @@
 # Read ASN.1/PEM X.509 certificate requests (PKCS#10 format) on stdin, 
 # parse each into plain text, then build substrate from it
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2314, pem
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat certificateRequest.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat certificateRequest.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 certType = rfc2314.CertificationRequest()
@@ -28,7 +29,7 @@ while 1:
 
     if rest: substrate = substrate[:-len(rest)]
         
-    print(cert.prettyPrint())
+    print((cert.prettyPrint()))
 
     assert encoder.encode(cert, defMode=False) == substrate or \
            encoder.encode(cert, defMode=True) == substrate, \
@@ -36,4 +37,4 @@ while 1:
         
     certCnt = certCnt + 1
     
-print('*** %s PEM certificate request(s) de/serialized' % certCnt)
+print(('*** %s PEM certificate request(s) de/serialized' % certCnt))
diff --git a/python/pyasn1-modules/tools/pkcs1dump.py b/python/pyasn1-modules/tools/pkcs1dump.py
index d0da82b2fb..ff350c1076 100755
--- a/python/pyasn1-modules/tools/pkcs1dump.py
+++ b/python/pyasn1-modules/tools/pkcs1dump.py
@@ -4,13 +4,14 @@
 # stdin, print them pretty and encode back into original wire format.
 # Private keys can be generated with "openssl genrsa|gendsa" commands.
 #
+from __future__ import print_function
 from pyasn1_modules import rfc2459, rfc2437, pem
 from pyasn1.codec.der import encoder, decoder
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat rsakey.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat rsakey.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 cnt = 0
@@ -31,7 +32,7 @@ while 1:
 
     if rest: substrate = substrate[:-len(rest)]
         
-    print(key.prettyPrint())
+    print((key.prettyPrint()))
 
     assert encoder.encode(key, defMode=False) == substrate or \
            encoder.encode(key, defMode=True) == substrate, \
@@ -39,4 +40,4 @@ while 1:
         
     cnt = cnt + 1
  
-print('*** %s key(s) re/serialized' % cnt)
+print(('*** %s key(s) re/serialized' % cnt))
diff --git a/python/pyasn1-modules/tools/pkcs7dump.py b/python/pyasn1-modules/tools/pkcs7dump.py
index 7794871620..e47ba940c3 100755
--- a/python/pyasn1-modules/tools/pkcs7dump.py
+++ b/python/pyasn1-modules/tools/pkcs7dump.py
@@ -3,13 +3,14 @@
 # Read ASN.1/PEM PKCS#7 on stdin, parse it into plain text,
 # then build substrate from it
 #
+from __future__ import print_function
 from pyasn1_modules import rfc2315, pem
 from pyasn1.codec.der import encoder, decoder
 import sys
     
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat pkcs7Certificate.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat pkcs7Certificate.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 idx, substrate = pem.readPemBlocksFromFile(
@@ -22,7 +23,7 @@ contentInfo, rest = decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo())
 
 if rest: substrate = substrate[:-len(rest)]
     
-print(contentInfo.prettyPrint())
+print((contentInfo.prettyPrint()))
 
 assert encoder.encode(contentInfo, defMode=False) == substrate or \
        encoder.encode(contentInfo, defMode=True) == substrate, \
@@ -44,4 +45,4 @@ content, _ = decoder.decode(
     asn1Spec=contentInfoMap[contentType]
     )
 
-print(content.prettyPrint())
+print((content.prettyPrint()))
diff --git a/python/pyasn1-modules/tools/pkcs8dump.py b/python/pyasn1-modules/tools/pkcs8dump.py
index d1d125f8cc..fa82a57d45 100755
--- a/python/pyasn1-modules/tools/pkcs8dump.py
+++ b/python/pyasn1-modules/tools/pkcs8dump.py
@@ -3,13 +3,14 @@
 # Read  bunch of ASN.1/PEM plain/encrypted private keys in PKCS#8 
 # format on stdin, parse each into plain text, then build substrate from it
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc5208, pem
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat pkcs8key.pem | %s""" % sys.argv[0])
+    print(("""Usage:
+$ cat pkcs8key.pem | %s""" % sys.argv[0]))
     sys.exit(-1)
     
 cnt = 0
@@ -30,7 +31,7 @@ while 1:
 
     if rest: substrate = substrate[:-len(rest)]
         
-    print(key.prettyPrint())
+    print((key.prettyPrint()))
 
     assert encoder.encode(key, defMode=False) == substrate or \
            encoder.encode(key, defMode=True) == substrate, \
@@ -38,4 +39,4 @@ while 1:
         
     cnt = cnt + 1
     
-print('*** %s PKCS#8 key(s) de/serialized' % cnt)
+print(('*** %s PKCS#8 key(s) de/serialized' % cnt))
diff --git a/python/pyasn1-modules/tools/snmpget.py b/python/pyasn1-modules/tools/snmpget.py
index 372510329b..394bfd4eff 100755
--- a/python/pyasn1-modules/tools/snmpget.py
+++ b/python/pyasn1-modules/tools/snmpget.py
@@ -2,13 +2,14 @@
 #
 # Generate SNMPGET request, parse response
 #
+from __future__ import print_function
 from pyasn1.codec.ber import encoder, decoder
 from pyasn1_modules import rfc1157
 import sys, socket
 
 if len(sys.argv) != 4:
-    print("""Usage:
-$ %s   """ % sys.argv[0])
+    print(("""Usage:
+$ %s   """ % sys.argv[0]))
     sys.exit(-1)
 
 msg = rfc1157.Message()
@@ -25,7 +26,7 @@ vb = vbl.setComponentByPosition(0).getComponentByPosition(0)
 vb.setComponentByPosition(0, sys.argv[3])
 v = vb.setComponentByPosition(1).getComponentByPosition(1).setComponentByPosition(0).getComponentByPosition(0).setComponentByPosition(3).getComponentByPosition(3)
 
-print('sending: %s' % msg.prettyPrint())
+print(('sending: %s' % msg.prettyPrint()))
 
 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 sock.sendto(encoder.encode(msg), (sys.argv[2], 161))
@@ -34,4 +35,4 @@ substrate, _ = sock.recvfrom(2048)
 
 rMsg, _ = decoder.decode(substrate, asn1Spec=msg)
 
-print('received: %s' % rMsg.prettyPrint())
+print(('received: %s' % rMsg.prettyPrint()))
diff --git a/python/pyasn1-modules/tools/x509dump.py b/python/pyasn1-modules/tools/x509dump.py
index 64cba7e305..d95206fa74 100755
--- a/python/pyasn1-modules/tools/x509dump.py
+++ b/python/pyasn1-modules/tools/x509dump.py
@@ -3,14 +3,15 @@
 # Read ASN.1/PEM X.509 certificates on stdin, parse each into plain text,
 # then build substrate from it
 #
+from __future__ import print_function
 from pyasn1.codec.der import decoder, encoder
 from pyasn1_modules import rfc2459, pem
 import sys
 
 if len(sys.argv) != 1:
-    print("""Usage:
-$ cat CACertificate.pem | %s
-$ cat userCertificate.pem | %s""" % (sys.argv[0], sys.argv[0]))
+    print(("""Usage:
+$ cat CACertificate.pem | {}
+$ cat userCertificate.pem | {}""".format(sys.argv[0], sys.argv[0])))
     sys.exit(-1)
     
 certType = rfc2459.Certificate()
@@ -29,7 +30,7 @@ while 1:
 
     if rest: substrate = substrate[:-len(rest)]
         
-    print(cert.prettyPrint())
+    print((cert.prettyPrint()))
 
     assert encoder.encode(cert, defMode=False) == substrate or \
            encoder.encode(cert, defMode=True) == substrate, \
@@ -37,4 +38,4 @@ while 1:
         
     certCnt = certCnt + 1
     
-print('*** %s PEM cert(s) de/serialized' % certCnt)
+print(('*** %s PEM cert(s) de/serialized' % certCnt))
diff --git a/python/pyasn1/pyasn1/codec/ber/decoder.py b/python/pyasn1/pyasn1/codec/ber/decoder.py
index be0cf49074..abddc95dee 100644
--- a/python/pyasn1/pyasn1/codec/ber/decoder.py
+++ b/python/pyasn1/pyasn1/codec/ber/decoder.py
@@ -8,17 +8,17 @@ class AbstractDecoder:
     protoComponent = None
     def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                      length, state, decodeFun, substrateFun):
-        raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))
+        raise error.PyAsn1Error('Decoder not implemented for {}'.format(tagSet))
 
     def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                      length, state, decodeFun, substrateFun):
-        raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))
+        raise error.PyAsn1Error('Indefinite length mode decoder not implemented for {}'.format(tagSet))
 
 class AbstractSimpleDecoder(AbstractDecoder):
     tagFormats = (tag.tagFormatSimple,)
     def _createComponent(self, asn1Spec, tagSet, value=None):
         if tagSet[0][1] not in self.tagFormats:
-            raise error.PyAsn1Error('Invalid tag format %r for %r' % (tagSet[0], self.protoComponent,))
+            raise error.PyAsn1Error('Invalid tag format {!r} for {!r}'.format(tagSet[0], self.protoComponent))
         if asn1Spec is None:
             return self.protoComponent.clone(value, tagSet)
         elif value is None:
@@ -30,7 +30,7 @@ class AbstractConstructedDecoder(AbstractDecoder):
     tagFormats = (tag.tagFormatConstructed,)
     def _createComponent(self, asn1Spec, tagSet, value=None):
         if tagSet[0][1] not in self.tagFormats:
-            raise error.PyAsn1Error('Invalid tag format %r for %r' % (tagSet[0], self.protoComponent,))
+            raise error.PyAsn1Error('Invalid tag format {!r} for {!r}'.format(tagSet[0], self.protoComponent))
         if asn1Spec is None:
             return self.protoComponent.clone(tagSet)
         else:
@@ -238,7 +238,7 @@ class ObjectIdentifierDecoder(AbstractSimpleDecoder):
                     subId = (subId << 7) + (nextSubId & 0x7F)
                     if index >= substrateLen:
                         raise error.SubstrateUnderrunError(
-                            'Short substrate for sub-OID past %s' % (oid,)
+                            'Short substrate for sub-OID past {}'.format(oid)
                             )
                     nextSubId = oct2int(head[index])
                     index = index + 1
@@ -568,7 +568,7 @@ typeMap = {
 
 ( stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec,
   stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue,
-  stDumpRawValue, stErrorCondition, stStop ) = [x for x in range(10)]
+  stDumpRawValue, stErrorCondition, stStop ) = (x for x in range(10))
 
 class Decoder:
     defaultErrorState = stErrorCondition
@@ -711,7 +711,7 @@ class Decoder:
                     else:
                         state = stTryAsExplicitTag
                 if debug.logger and debug.logger & debug.flagDecoder:
-                    debug.logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "", state == stDecodeValue and 'value' or 'as explicit tag'))
+                    debug.logger('codec {} chosen by a built-in type, decoding {}'.format(concreteDecoder and concreteDecoder.__class__.__name__ or "", state == stDecodeValue and 'value' or 'as explicit tag'))
                     debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
             if state == stGetValueDecoderByAsn1Spec:
                 if isinstance(asn1Spec, (dict, tagmap.TagMap)):
@@ -722,12 +722,12 @@ class Decoder:
                     if debug.logger and debug.logger & debug.flagDecoder:
                         debug.logger('candidate ASN.1 spec is a map of:')
                         for t, v in asn1Spec.getPosMap().items():
-                            debug.logger('  %r -> %s' % (t, v.__class__.__name__))
+                            debug.logger('  {!r} -> {}'.format(t, v.__class__.__name__))
                         if asn1Spec.getNegMap():
                             debug.logger('but neither of: ')
                             for i in asn1Spec.getNegMap().items():
-                                debug.logger('  %r -> %s' % (t, v.__class__.__name__))
-                        debug.logger('new candidate ASN.1 spec is %s, chosen by %r' % (__chosenSpec is None and '' or __chosenSpec.__class__.__name__, tagSet))
+                                debug.logger('  {!r} -> {}'.format(t, v.__class__.__name__))
+                        debug.logger('new candidate ASN.1 spec is {}, chosen by {!r}'.format(__chosenSpec is None and '' or __chosenSpec.__class__.__name__, tagSet))
                 else:
                     __chosenSpec = asn1Spec
                     debug.logger and debug.logger & debug.flagDecoder and debug.logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
@@ -741,11 +741,11 @@ class Decoder:
                            __chosenSpec.typeId in self.__typeMap:
                         # ambiguous type
                         concreteDecoder = self.__typeMap[__chosenSpec.typeId]
-                        debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen for an ambiguous type by type ID %s' % (__chosenSpec.typeId,))
+                        debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen for an ambiguous type by type ID {}'.format(__chosenSpec.typeId))
                     elif baseTagSet in self.__tagMap:
                         # base type or tagged subtype
                         concreteDecoder = self.__tagMap[baseTagSet]
-                        debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen by base %r' % (baseTagSet,))
+                        debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen by base {!r}'.format(baseTagSet))
                     else:
                         concreteDecoder = None
                     if concreteDecoder:
@@ -761,7 +761,7 @@ class Decoder:
                     concreteDecoder = None
                     state = stTryAsExplicitTag
                 if debug.logger and debug.logger & debug.flagDecoder:
-                    debug.logger('codec %s chosen by ASN.1 spec, decoding %s' % (state == stDecodeValue and concreteDecoder.__class__.__name__ or "", state == stDecodeValue and 'value' or 'as explicit tag'))
+                    debug.logger('codec {} chosen by ASN.1 spec, decoding {}'.format(state == stDecodeValue and concreteDecoder.__class__.__name__ or "", state == stDecodeValue and 'value' or 'as explicit tag'))
                     debug.scope.push(__chosenSpec is None and '?' or __chosenSpec.__class__.__name__)
             if state == stTryAsExplicitTag:
                 if tagSet and \
@@ -773,7 +773,7 @@ class Decoder:
                 else:                    
                     concreteDecoder = None
                     state = self.defaultErrorState
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "", state == stDecodeValue and 'value' or 'as failure'))
+                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec {} chosen, decoding {}'.format(concreteDecoder and concreteDecoder.__class__.__name__ or "", state == stDecodeValue and 'value' or 'as failure'))
             if state == stDumpRawValue:
                 concreteDecoder = self.defaultRawDecoder
                 debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
@@ -792,10 +792,10 @@ class Decoder:
                         stGetValueDecoder, self, substrateFun
                         )
                 state = stStop
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or ''))
+                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec {} yields type {}, value:\n{}\n...remaining substrate is: {}'.format(concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or ''))
             if state == stErrorCondition:
                 raise error.PyAsn1Error(
-                    '%r not in asn1Spec: %r' % (tagSet, asn1Spec)
+                    '{!r} not in asn1Spec: {!r}'.format(tagSet, asn1Spec)
                     )
         if debug.logger and debug.logger & debug.flagDecoder:
             debug.scope.pop()
diff --git a/python/pyasn1/pyasn1/codec/ber/encoder.py b/python/pyasn1/pyasn1/codec/ber/encoder.py
index 173949d0b6..7e5c7129a4 100644
--- a/python/pyasn1/pyasn1/codec/ber/encoder.py
+++ b/python/pyasn1/pyasn1/codec/ber/encoder.py
@@ -164,12 +164,12 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
             index = 5
         else:
             if len(oid) < 2:
-                raise error.PyAsn1Error('Short OID %s' % (value,))
+                raise error.PyAsn1Error('Short OID {}'.format(value))
 
             # Build the first twos
             if oid[0] > 6 or oid[1] > 39 or oid[0] == 6 and oid[1] > 15:
                 raise error.PyAsn1Error(
-                    'Initial sub-ID overflow %s in OID %s' % (oid[:2], value)
+                    'Initial sub-ID overflow {} in OID {}'.format(oid[:2], value)
                     )
             octets = (oid[0] * 40 + oid[1],)
             index = 2
@@ -181,7 +181,7 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
                 octets = octets + (subid & 0x7f,)
             elif subid < 0 or subid > 0xFFFFFFFF:
                 raise error.PyAsn1Error(
-                    'SubId overflow %s in %s' % (subid, value)
+                    'SubId overflow {} in {}'.format(subid, value)
                     )
             else:
                 # Pack large Sub-Object IDs
@@ -328,7 +328,7 @@ class Encoder:
         self.__typeMap = typeMap
 
     def __call__(self, value, defMode=1, maxChunkSize=0):
-        debug.logger & debug.flagEncoder and debug.logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not defMode and 'in' or '', maxChunkSize, value.__class__.__name__, value.prettyPrint()))
+        debug.logger & debug.flagEncoder and debug.logger('encoder called in {}def mode, chunk size {} for type {}, value:\n{}'.format(not defMode and 'in' or '', maxChunkSize, value.__class__.__name__, value.prettyPrint()))
         tagSet = value.getTagSet()
         if len(tagSet) > 1:
             concreteEncoder = explicitlyTaggedItemEncoder
@@ -342,12 +342,12 @@ class Encoder:
                 if tagSet in self.__tagMap:
                     concreteEncoder = self.__tagMap[tagSet]
                 else:
-                    raise Error('No encoder for %s' % (value,))
-        debug.logger & debug.flagEncoder and debug.logger('using value codec %s chosen by %r' % (concreteEncoder.__class__.__name__, tagSet))
+                    raise Error('No encoder for {}'.format(value))
+        debug.logger & debug.flagEncoder and debug.logger('using value codec {} chosen by {!r}'.format(concreteEncoder.__class__.__name__, tagSet))
         substrate = concreteEncoder.encode(
             self, value, defMode, maxChunkSize
             )
-        debug.logger & debug.flagEncoder and debug.logger('built %s octets of substrate: %s\nencoder completed' % (len(substrate), debug.hexdump(substrate)))
+        debug.logger & debug.flagEncoder and debug.logger('built {} octets of substrate: {}\nencoder completed'.format(len(substrate), debug.hexdump(substrate)))
         return substrate
 
 encode = Encoder(tagMap, typeMap)
diff --git a/python/pyasn1/pyasn1/debug.py b/python/pyasn1/pyasn1/debug.py
index c27cb1d446..080fb1700d 100644
--- a/python/pyasn1/pyasn1/debug.py
+++ b/python/pyasn1/pyasn1/debug.py
@@ -22,12 +22,12 @@ class Debug:
         self('running pyasn1 version %s' % __version__)
         for f in flags:
             if f not in flagMap:
-                raise error.PyAsn1Error('bad debug flag %s' % (f,))
+                raise error.PyAsn1Error('bad debug flag {}'.format(f))
             self._flags = self._flags | flagMap[f]
             self('debug category \'%s\' enabled' % f)
         
     def __str__(self):
-        return 'logger %s, flags %x' % (self._printer, self._flags)
+        return 'logger {}, flags {:x}'.format(self._printer, self._flags)
     
     def __call__(self, msg):
         self._printer('DBG: %s\n' % msg)
@@ -46,8 +46,8 @@ def setLogger(l):
 
 def hexdump(octets):
     return ' '.join(
-            [ '%s%.2X' % (n%16 == 0 and ('\n%.5d: ' % n) or '', x) 
-              for n,x in zip(range(len(octets)), octs2ints(octets)) ]
+            [ '{}{:.2X}'.format(n%16 == 0 and ('\n%.5d: ' % n) or '', x) 
+              for n,x in zip(list(range(len(octets))), octs2ints(octets)) ]
         )
 
 class Scope:
diff --git a/python/pyasn1/pyasn1/type/base.py b/python/pyasn1/pyasn1/type/base.py
index 40873719ca..9391b85eb6 100644
--- a/python/pyasn1/pyasn1/type/base.py
+++ b/python/pyasn1/pyasn1/type/base.py
@@ -30,7 +30,7 @@ class Asn1ItemBase(Asn1Item):
             self._subtypeSpec(value, idx)
         except error.PyAsn1Error:
             c, i, t = sys.exc_info()
-            raise c('%s at %s' % (i, self.__class__.__name__))
+            raise c('{} at {}'.format(i, self.__class__.__name__))
         
     def getSubtypeSpec(self): return self._subtypeSpec
     
@@ -75,7 +75,7 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
         if self._value is noValue:
             return self.__class__.__name__ + '()'
         else:
-            return self.__class__.__name__ + '(%s)' % (self.prettyOut(self._value),)
+            return self.__class__.__name__ + '({})'.format(self.prettyOut(self._value))
     def __str__(self): return str(self._value)
     def __eq__(self, other):
         return self is other and True or self._value == other
@@ -170,7 +170,7 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
         for idx in range(len(self._componentValues)):
             if self._componentValues[idx] is None:
                 continue
-            r = r + '.setComponentByPosition(%s, %r)' % (
+            r = r + '.setComponentByPosition({}, {!r})'.format(
                 idx, self._componentValues[idx]
                 )
         return r
diff --git a/python/pyasn1/pyasn1/type/constraint.py b/python/pyasn1/pyasn1/type/constraint.py
index 66873937d8..a02c37eaf9 100644
--- a/python/pyasn1/pyasn1/type/constraint.py
+++ b/python/pyasn1/pyasn1/type/constraint.py
@@ -29,10 +29,10 @@ class AbstractConstraint:
             self._testValue(value, idx)
         except error.ValueConstraintError:
             raise error.ValueConstraintError(
-               '%s failed at: \"%s\"' % (self, sys.exc_info()[1])
+               '{} failed at: \"{}\"'.format(self, sys.exc_info()[1])
             )
     def __repr__(self):
-        return '%s(%s)' % (
+        return '{}({})'.format(
             self.__class__.__name__,
             ', '.join([repr(x) for x in self._values])
         )
@@ -88,12 +88,12 @@ class ValueRangeConstraint(AbstractConstraint):
     def _setValues(self, values):
         if len(values) != 2:
             raise error.PyAsn1Error(
-                '%s: bad constraint values' % (self.__class__.__name__,)
+                '{}: bad constraint values'.format(self.__class__.__name__)
                 )
         self.start, self.stop = values
         if self.start > self.stop:
             raise error.PyAsn1Error(
-                '%s: screwed constraint values (start > stop): %s > %s' % (
+                '{}: screwed constraint values (start > stop): {} > {}'.format(
                     self.__class__.__name__,
                     self.start, self.stop
                 )
@@ -193,7 +193,7 @@ class ConstraintsUnion(AbstractConstraintSet):
             else:
                 return
         raise error.ValueConstraintError(
-            'all of %s failed for \"%s\"' % (self._values, value)
+            'all of {} failed for \"{}\"'.format(self._values, value)
             )
 
 # XXX
diff --git a/python/pyasn1/pyasn1/type/namedtype.py b/python/pyasn1/pyasn1/type/namedtype.py
index 48967a5fe2..b18ad30db5 100644
--- a/python/pyasn1/pyasn1/type/namedtype.py
+++ b/python/pyasn1/pyasn1/type/namedtype.py
@@ -8,7 +8,7 @@ class NamedType:
     isDefaulted = 0
     def __init__(self, name, t):
         self.__name = name; self.__type = t
-    def __repr__(self): return '%s(%s, %s)' % (
+    def __repr__(self): return '{}({}, {})'.format(
         self.__class__.__name__, self.__name, self.__type
         )
     def getType(self): return self.__type
@@ -35,7 +35,7 @@ class NamedTypes:
     def __repr__(self):
         r = '%s(' % self.__class__.__name__
         for n in self.__namedTypes:
-            r = r + '%r, ' % (n,)
+            r = r + '{!r}, '.format(n)
         return r + ')'
     
     def __getitem__(self, idx): return self.__namedTypes[idx]
@@ -60,12 +60,12 @@ class NamedTypes:
                 tagMap = self.__namedTypes[idx].getType().getTagMap()
                 for t in tagMap.getPosMap():
                     if t in self.__tagToPosIdx:
-                        raise error.PyAsn1Error('Duplicate type %s' % (t,))
+                        raise error.PyAsn1Error('Duplicate type {}'.format(t))
                     self.__tagToPosIdx[t] = idx
         try:
             return self.__tagToPosIdx[tagSet]
         except KeyError:
-            raise error.PyAsn1Error('Type %s not found' % (tagSet,))
+            raise error.PyAsn1Error('Type {} not found'.format(tagSet))
         
     def getNameByPosition(self, idx):
         try:
@@ -79,12 +79,12 @@ class NamedTypes:
                 idx = idx - 1
                 n = self.__namedTypes[idx].getName()
                 if n in self.__nameToPosIdx:
-                    raise error.PyAsn1Error('Duplicate name %s' % (n,))
+                    raise error.PyAsn1Error('Duplicate name {}'.format(n))
                 self.__nameToPosIdx[n] = idx
         try:
             return self.__nameToPosIdx[name]
         except KeyError:
-            raise error.PyAsn1Error('Name %s not found' % (name,))
+            raise error.PyAsn1Error('Name {} not found'.format(name))
 
     def __buildAmbigiousTagMap(self):
         ambigiousTypes = ()
diff --git a/python/pyasn1/pyasn1/type/namedval.py b/python/pyasn1/pyasn1/type/namedval.py
index d0fea7cc7c..26267eb1df 100644
--- a/python/pyasn1/pyasn1/type/namedval.py
+++ b/python/pyasn1/pyasn1/type/namedval.py
@@ -15,10 +15,10 @@ class NamedValues:
                 name = namedValue
                 val = automaticVal
             if name in self.nameToValIdx:
-                raise error.PyAsn1Error('Duplicate name %s' % (name,))
+                raise error.PyAsn1Error('Duplicate name {}'.format(name))
             self.nameToValIdx[name] = val
             if val in self.valToNameIdx:
-                raise error.PyAsn1Error('Duplicate value %s=%s' % (name, val))
+                raise error.PyAsn1Error('Duplicate value {}={}'.format(name, val))
             self.valToNameIdx[val] = name
             self.namedValues = self.namedValues + ((name, val),)
             automaticVal = automaticVal + 1
diff --git a/python/pyasn1/pyasn1/type/tag.py b/python/pyasn1/pyasn1/type/tag.py
index 1144907fa1..17122a59c3 100644
--- a/python/pyasn1/pyasn1/type/tag.py
+++ b/python/pyasn1/pyasn1/type/tag.py
@@ -18,7 +18,7 @@ class Tag:
     def __init__(self, tagClass, tagFormat, tagId):
         if tagId < 0:
             raise error.PyAsn1Error(
-                'Negative tag ID (%s) not allowed' % (tagId,)
+                'Negative tag ID ({}) not allowed'.format(tagId)
                 )
         self.__tag = (tagClass, tagFormat, tagId)
         self.uniq = (tagClass, tagId)
@@ -64,7 +64,7 @@ class TagSet:
         self.__lenOfSuperTags = len(superTags)
         
     def __repr__(self):
-        return '%s(%s)' % (
+        return '{}({})'.format(
             self.__class__.__name__,
             ', '.join([repr(x) for x in self.__superTags])
             )
diff --git a/python/pyasn1/pyasn1/type/tagmap.py b/python/pyasn1/pyasn1/type/tagmap.py
index 7cec3a10e4..5714487b49 100644
--- a/python/pyasn1/pyasn1/type/tagmap.py
+++ b/python/pyasn1/pyasn1/type/tagmap.py
@@ -21,14 +21,14 @@ class TagMap:
             raise KeyError()
 
     def __repr__(self):
-        s = '%r/%r' % (self.__posMap, self.__negMap)
+        s = '{!r}/{!r}'.format(self.__posMap, self.__negMap)
         if self.__defType is not None:
-            s = s + '/%r' % (self.__defType,)
+            s = s + '/{!r}'.format(self.__defType)
         return s
 
     def clone(self, parentType, tagMap, uniq=False):
         if self.__defType is not None and tagMap.getDef() is not None:
-            raise error.PyAsn1Error('Duplicate default value at %s' % (self,))
+            raise error.PyAsn1Error('Duplicate default value at {}'.format(self))
         if tagMap.getDef() is not None:
             defType = tagMap.getDef()
         else:
@@ -37,7 +37,7 @@ class TagMap:
         posMap = self.__posMap.copy()
         for k in tagMap.getPosMap():
             if uniq and k in posMap:
-                raise error.PyAsn1Error('Duplicate positive key %s' % (k,))
+                raise error.PyAsn1Error('Duplicate positive key {}'.format(k))
             posMap[k] = parentType
 
         negMap = self.__negMap.copy()
diff --git a/python/pyasn1/pyasn1/type/univ.py b/python/pyasn1/pyasn1/type/univ.py
index 9cd16f8a2a..12bdbad339 100644
--- a/python/pyasn1/pyasn1/type/univ.py
+++ b/python/pyasn1/pyasn1/type/univ.py
@@ -55,7 +55,7 @@ class Integer(base.AbstractSimpleAsn1Item):
 
     def __int__(self): return int(self._value)
     if sys.version_info[0] <= 2:
-        def __long__(self): return long(self._value)
+        def __long__(self): return int(self._value)
     def __float__(self): return float(self._value)    
     def __abs__(self): return abs(self._value)
     def __index__(self): return int(self._value)
@@ -73,7 +73,7 @@ class Integer(base.AbstractSimpleAsn1Item):
                 return int(value)
             except:
                 raise error.PyAsn1Error(
-                    'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
+                    'Can\'t coerce {} into integer: {}'.format(value, sys.exc_info()[1])
                     )
         r = self.__namedValues.getValue(value)
         if r is not None:
@@ -82,7 +82,7 @@ class Integer(base.AbstractSimpleAsn1Item):
             return int(value)
         except:
             raise error.PyAsn1Error(
-                'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
+                'Can\'t coerce {} into integer: {}'.format(value, sys.exc_info()[1])
                 )
 
     def prettyOut(self, value):
@@ -216,7 +216,7 @@ class BitString(base.AbstractSimpleAsn1Item):
                             r.append(1)
                         else:
                             raise error.PyAsn1Error(
-                                'Non-binary BIT STRING initializer %s' % (v,)
+                                'Non-binary BIT STRING initializer {}'.format(v)
                                 )
                     return tuple(r)
                 elif value[-2:] == '\'H':
@@ -229,14 +229,14 @@ class BitString(base.AbstractSimpleAsn1Item):
                     return tuple(r)
                 else:
                     raise error.PyAsn1Error(
-                        'Bad BIT STRING value notation %s' % (value,)
+                        'Bad BIT STRING value notation {}'.format(value)
                         )                
             else:
                 for i in value.split(','):
                     j = self.__namedValues.getValue(i)
                     if j is None:
                         raise error.PyAsn1Error(
-                            'Unknown bit identifier \'%s\'' % (i,)
+                            'Unknown bit identifier \'{}\''.format(i)
                             )
                     if j >= len(r):
                         r.extend([0]*(j-len(r)+1))
@@ -247,14 +247,14 @@ class BitString(base.AbstractSimpleAsn1Item):
             for b in r:
                 if b and b != 1:
                     raise error.PyAsn1Error(
-                        'Non-binary BitString initializer \'%s\'' % (r,)
+                        'Non-binary BitString initializer \'{}\''.format(r)
                         )
             return r
         elif isinstance(value, BitString):
             return tuple(value)
         else:
             raise error.PyAsn1Error(
-                'Bad BitString initializer type \'%s\'' % (value,)
+                'Bad BitString initializer type \'{}\''.format(value)
                 )
 
     def prettyOut(self, value):
@@ -309,7 +309,7 @@ class OctetString(base.AbstractSimpleAsn1Item):
                     return ''.join([ chr(x) for x in value ])
                 except ValueError:
                     raise error.PyAsn1Error(
-                        'Bad OctetString initializer \'%s\'' % (value,)
+                        'Bad OctetString initializer \'{}\''.format(value)
                         )                
             else:
                 return str(value)
@@ -324,14 +324,14 @@ class OctetString(base.AbstractSimpleAsn1Item):
                     return bytes(value)
                 except ValueError:
                     raise error.PyAsn1Error(
-                        'Bad OctetString initializer \'%s\'' % (value,)
+                        'Bad OctetString initializer \'{}\''.format(value)
                         )
             else:
                 try:
                     return str(value).encode(self._encoding)
                 except UnicodeEncodeError:
                     raise error.PyAsn1Error(
-                        'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding)
+                        'Can\'t encode string \'{}\' with \'{}\' codec'.format(value, self._encoding)
                         )
                         
 
@@ -350,7 +350,7 @@ class OctetString(base.AbstractSimpleAsn1Item):
                 v = 1
             else:
                 raise error.PyAsn1Error(
-                    'Non-binary OCTET STRING initializer %s' % (v,)
+                    'Non-binary OCTET STRING initializer {}'.format(v)
                     )
             byte = byte | (v << bitNo)
         return octets.ints2octs(r + (byte,))
@@ -421,14 +421,14 @@ class OctetString(base.AbstractSimpleAsn1Item):
     def __rmul__(self, value): return self * value
 
 class Null(OctetString):
-    defaultValue = ''.encode()  # This is tightly constrained
+    defaultValue = b''  # This is tightly constrained
     tagSet = baseTagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
         )
-    subtypeSpec = OctetString.subtypeSpec+constraint.SingleValueConstraint(''.encode())
+    subtypeSpec = OctetString.subtypeSpec+constraint.SingleValueConstraint(b'')
     
 if sys.version_info[0] <= 2:
-    intTypes = (int, long)
+    intTypes = int
 else:
     intTypes = int
 
@@ -496,7 +496,7 @@ class ObjectIdentifier(base.AbstractSimpleAsn1Item):
         for x in value:
             if not isinstance(x, intTypes) or x < 0:
                 raise error.PyAsn1Error(
-                    'Invalid sub-ID in %s at %s' % (value, self.__class__.__name__)
+                    'Invalid sub-ID in {} at {}'.format(value, self.__class__.__name__)
                     )
     
         return value
@@ -529,11 +529,11 @@ class Real(base.AbstractSimpleAsn1Item):
             for d in value:
                 if not isinstance(d, intTypes):
                     raise error.PyAsn1Error(
-                        'Lame Real value syntax: %s' % (value,)
+                        'Lame Real value syntax: {}'.format(value)
                         )
             if value[1] not in (2, 10):
                 raise error.PyAsn1Error(
-                    'Prohibited base for Real value: %s' % (value[1],)
+                    'Prohibited base for Real value: {}'.format(value[1])
                     )
             if value[1] == 10:
                 value = self.__normalizeBase10(value)
@@ -557,7 +557,7 @@ class Real(base.AbstractSimpleAsn1Item):
             except ValueError:
                 pass
         raise error.PyAsn1Error(
-            'Bad real value syntax: %s' % (value,)
+            'Bad real value syntax: {}'.format(value)
             )
         
     def prettyOut(self, value):
@@ -594,7 +594,7 @@ class Real(base.AbstractSimpleAsn1Item):
 
     def __int__(self): return int(float(self))
     if sys.version_info[0] <= 2:
-        def __long__(self): return long(float(self))
+        def __long__(self): return int(float(self))
     def __float__(self):
         if self._value in self._inf:
             return self._value
@@ -653,7 +653,7 @@ class SetOf(base.AbstractConstructedAsn1Item):
     def _verifyComponent(self, idx, value):
         if self._componentType is not None and \
                not self._componentType.isSuperTypeOf(value):
-            raise error.PyAsn1Error('Component type error %s' % (value,))
+            raise error.PyAsn1Error('Component type error {}'.format(value))
 
     def getComponentByPosition(self, idx): return self._componentValues[idx]
     def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
@@ -748,7 +748,7 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
                 )
         t = self._componentType[idx].getType()
         if not t.isSuperTypeOf(value):
-            raise error.PyAsn1Error('Component type error %r vs %r' % (t, value))
+            raise error.PyAsn1Error('Component type error {!r} vs {!r}'.format(t, value))
 
     def getComponentByName(self, name):
         return self.getComponentByPosition(
@@ -815,7 +815,7 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
             elif not self._componentType[idx].isOptional:
                 if self.getComponentByPosition(idx) is None:
                     raise error.PyAsn1Error(
-                        'Uninitialized component #%s at %r' % (idx, self)
+                        'Uninitialized component #{} at {!r}'.format(idx, self)
                         )
 
     def prettyPrint(self, scope=0):
@@ -829,7 +829,7 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
                     r = r + ''
                 else:
                     r = r + componentType.getNameByPosition(idx)
-                r = '%s=%s\n' % (
+                r = '{}={}\n'.format(
                     r, self._componentValues[idx].prettyPrint(scope)
                     )
         return r
diff --git a/python/pyasn1/setup.py b/python/pyasn1/setup.py
index 194f0c8ca8..9637798bc4 100644
--- a/python/pyasn1/setup.py
+++ b/python/pyasn1/setup.py
@@ -4,6 +4,7 @@
    A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
 """
 
+from __future__ import print_function
 import os
 import sys
 
diff --git a/python/pyasn1/test/codec/ber/suite.py b/python/pyasn1/test/codec/ber/suite.py
index 796c526b4b..4227dc1cfb 100644
--- a/python/pyasn1/test/codec/ber/suite.py
+++ b/python/pyasn1/test/codec/ber/suite.py
@@ -1,7 +1,7 @@
 from sys import path, version_info
 from os.path import sep
 path.insert(1, path[0]+sep+'ber')
-import test_encoder, test_decoder
+from . import test_encoder, test_decoder
 from pyasn1.error import PyAsn1Error
 if version_info[0:2] < (2, 7) or \
    version_info[0:2] in ( (3, 0), (3, 1) ):
diff --git a/python/pyasn1/test/codec/cer/suite.py b/python/pyasn1/test/codec/cer/suite.py
index 49d682918b..eecccbc5b5 100644
--- a/python/pyasn1/test/codec/cer/suite.py
+++ b/python/pyasn1/test/codec/cer/suite.py
@@ -1,7 +1,7 @@
 from sys import path, version_info
 from os.path import sep
 path.insert(1, path[0]+sep+'cer')
-import test_encoder, test_decoder
+from . import test_encoder, test_decoder
 from pyasn1.error import PyAsn1Error
 if version_info[0:2] < (2, 7) or \
    version_info[0:2] in ( (3, 0), (3, 1) ):
diff --git a/python/pyasn1/test/codec/der/suite.py b/python/pyasn1/test/codec/der/suite.py
index 7af83bf94f..7d73e3aa87 100644
--- a/python/pyasn1/test/codec/der/suite.py
+++ b/python/pyasn1/test/codec/der/suite.py
@@ -1,7 +1,7 @@
 from sys import path, version_info
 from os.path import sep
 path.insert(1, path[0]+sep+'der')
-import test_encoder, test_decoder
+from . import test_encoder, test_decoder
 from pyasn1.error import PyAsn1Error
 if version_info[0:2] < (2, 7) or \
    version_info[0:2] in ( (3, 0), (3, 1) ):
diff --git a/python/pyasn1/test/codec/der/test_decoder.py b/python/pyasn1/test/codec/der/test_decoder.py
index 5c9a1948b9..f2718d2115 100644
--- a/python/pyasn1/test/codec/der/test_decoder.py
+++ b/python/pyasn1/test/codec/der/test_decoder.py
@@ -14,7 +14,7 @@ else:
 class OctetStringDecoderTestCase(unittest.TestCase):
     def testShortMode(self):
         assert decoder.decode(
-            '\004\017Quick brown fox'.encode()
-            ) == ('Quick brown fox'.encode(), ''.encode())
+            b'\004\017Quick brown fox'
+            ) == (b'Quick brown fox', b'')
 
 if __name__ == '__main__': unittest.main()
diff --git a/python/pyasn1/test/codec/suite.py b/python/pyasn1/test/codec/suite.py
index 93ff063818..fe44b6bd50 100644
--- a/python/pyasn1/test/codec/suite.py
+++ b/python/pyasn1/test/codec/suite.py
@@ -1,11 +1,11 @@
 from sys import path, version_info
 from os.path import sep
 path.insert(1, path[0]+sep+'codec'+sep+'ber')
-import ber.suite
+from . import ber.suite
 path.insert(1, path[0]+sep+'codec'+sep+'cer')
-import cer.suite
+from . import cer.suite
 path.insert(1, path[0]+sep+'codec'+sep+'der')
-import der.suite
+from . import der.suite
 from pyasn1.error import PyAsn1Error
 if version_info[0:2] < (2, 7) or \
    version_info[0:2] in ( (3, 0), (3, 1) ):
diff --git a/python/pyasn1/test/suite.py b/python/pyasn1/test/suite.py
index b4d80e864a..11b121b2ce 100644
--- a/python/pyasn1/test/suite.py
+++ b/python/pyasn1/test/suite.py
@@ -1,9 +1,9 @@
 from sys import path, version_info
 from os.path import sep
 path.insert(1, path[0]+sep+'type')
-import type.suite
+from . import type.suite
 path.insert(1, path[0]+sep+'codec')
-import codec.suite
+from . import codec.suite
 from pyasn1.error import PyAsn1Error
 if version_info[0:2] < (2, 7) or \
    version_info[0:2] in ( (3, 0), (3, 1) ):
diff --git a/python/pyasn1/test/type/suite.py b/python/pyasn1/test/type/suite.py
index bc4b48685f..5dc46b0293 100644
--- a/python/pyasn1/test/type/suite.py
+++ b/python/pyasn1/test/type/suite.py
@@ -1,4 +1,4 @@
-import test_tag, test_constraint, test_namedtype, test_univ
+from . import test_tag, test_constraint, test_namedtype, test_univ
 from pyasn1.error import PyAsn1Error
 from sys import version_info
 if version_info[0:2] < (2, 7) or \
diff --git a/python/pylru/pylru.py b/python/pylru/pylru.py
index e69cadb76c..99efcdd406 100644
--- a/python/pylru/pylru.py
+++ b/python/pylru/pylru.py
@@ -1,4 +1,3 @@
-
 # Cache implementaion with a Least Recently Used (LRU) replacement policy and
 # a basic dictionary interface.
 
@@ -32,12 +31,12 @@
 # lookup of values by key.
 
 # Class for the node objects.
-class _dlnode(object):
+class _dlnode:
     def __init__(self):
         self.empty = True
 
 
-class lrucache(object):
+class lrucache:
 
     def __init__(self, size, callback=None):
 
@@ -287,7 +286,7 @@ class lrucache(object):
 
 
 
-class WriteThroughCacheManager(object):
+class WriteThroughCacheManager:
     def __init__(self, store, size):
         self.store = store
         self.cache = lrucache(size)
@@ -354,20 +353,20 @@ class WriteThroughCacheManager(object):
             pass
 
     def __iter__(self):
-        return self.keys()
+        return list(self.keys())
 
     def keys(self):
-        return self.store.keys()
+        return list(self.store.keys())
 
     def values(self):
-        return self.store.values()
+        return list(self.store.values())
 
     def items(self):
-        return self.store.items()
+        return list(self.store.items())
 
 
 
-class WriteBackCacheManager(object):
+class WriteBackCacheManager:
     def __init__(self, store, size):
         self.store = store
 
@@ -454,7 +453,7 @@ class WriteBackCacheManager(object):
 
 
     def __iter__(self):
-        return self.keys()
+        return list(self.keys())
 
     def keys(self):
         for key in self.store.keys():
@@ -501,7 +500,7 @@ class WriteBackCacheManager(object):
         return False
 
 
-class FunctionCacheManager(object):
+class FunctionCacheManager:
     def __init__(self, func, size):
         self.func = func
         self.cache = lrucache(size)
@@ -533,7 +532,7 @@ def lruwrap(store, size, writeback=False):
 
 import functools
 
-class lrudecorator(object):
+class lrudecorator:
     def __init__(self, size):
         self.cache = lrucache(size)
 
diff --git a/python/pylru/test.py b/python/pylru/test.py
index 7a4842fb52..67d170dc94 100644
--- a/python/pylru/test.py
+++ b/python/pylru/test.py
@@ -1,4 +1,3 @@
-
 from pylru import *
 import random
 
@@ -112,7 +111,7 @@ def testcache():
             q2.append((x, y))
 
         assert list(a.items()) == q2
-        assert list(zip(a.keys(), a.values())) == q2
+        assert list(zip(list(a.keys()), list(a.values()))) == q2
         assert list(a.keys()) == list(a)
 
 
diff --git a/python/pystache/pystache/__init__.py b/python/pystache/pystache/__init__.py
index 4cf24344e5..e04e99f330 100644
--- a/python/pystache/pystache/__init__.py
+++ b/python/pystache/pystache/__init__.py
@@ -1,4 +1,3 @@
-
 """
 TODO: add a docstring.
 
diff --git a/python/pystache/pystache/commands/render.py b/python/pystache/pystache/commands/render.py
index 1a9c309d52..c398a9f92c 100644
--- a/python/pystache/pystache/commands/render.py
+++ b/python/pystache/pystache/commands/render.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module provides command-line access to pystache.
 
@@ -8,6 +6,8 @@ Run this script using the -h option for command-line help.
 """
 
 
+from __future__ import print_function
+import six
 try:
     import json
 except:
@@ -22,7 +22,7 @@ except:
         from sys import exc_info
         ex_type, ex_value, tb = exc_info()
         new_ex = Exception("%s: %s" % (ex_type.__name__, ex_value))
-        raise new_ex.__class__, new_ex, tb
+        six.reraise(new_ex.__class__, new_ex, tb)
 
 # The optparse module is deprecated in Python 2.7 in favor of argparse.
 # However, argparse is not available in Python 2.6 and earlier.
@@ -88,7 +88,7 @@ def main(sys_argv=sys.argv):
         context = json.loads(context)
 
     rendered = renderer.render(template, context)
-    print rendered
+    print(rendered)
 
 
 if __name__=='__main__':
diff --git a/python/pystache/pystache/commands/test.py b/python/pystache/pystache/commands/test.py
index 0872453388..0f530e67ac 100644
--- a/python/pystache/pystache/commands/test.py
+++ b/python/pystache/pystache/commands/test.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module provides a command to test pystache (unit tests, doctests, etc).
 
diff --git a/python/pystache/pystache/common.py b/python/pystache/pystache/common.py
index fb266dd8b5..f2b2b477f0 100644
--- a/python/pystache/pystache/common.py
+++ b/python/pystache/pystache/common.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 Exposes functionality needed throughout the project.
 
@@ -13,9 +11,9 @@ def _get_string_types():
     #   and byte strings, and 2to3 seems to convert all of "str", "unicode",
     #   and "basestring" to Python 3's "str".
     if version_info < (3, ):
-         return basestring
+         return str
     # The latter evaluates to "bytes" in Python 3 -- even after conversion by 2to3.
-    return (unicode, type(u"a".encode('utf-8')))
+    return (str, type(b"a"))
 
 
 _STRING_TYPES = _get_string_types()
@@ -53,7 +51,7 @@ def read(path):
         f.close()
 
 
-class MissingTags(object):
+class MissingTags:
 
     """Contains the valid values for Renderer.missing_tags."""
 
diff --git a/python/pystache/pystache/context.py b/python/pystache/pystache/context.py
index 6715916092..3019146d98 100644
--- a/python/pystache/pystache/context.py
+++ b/python/pystache/pystache/context.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 Exposes a ContextStack class.
 
@@ -18,7 +16,7 @@ from pystache.common import PystacheError
 
 
 # This equals '__builtin__' in Python 2 and 'builtins' in Python 3.
-_BUILTIN_MODULE = type(0).__module__
+_BUILTIN_MODULE = int.__module__
 
 
 # We use this private global variable as a return value to represent a key
@@ -29,7 +27,7 @@ _BUILTIN_MODULE = type(0).__module__
 # TODO: eliminate the need for a private global variable, e.g. by using the
 #   preferred Python approach of "easier to ask for forgiveness than permission":
 #     http://docs.python.org/glossary.html#term-eafp
-class NotFound(object):
+class NotFound:
     pass
 _NOT_FOUND = NotFound()
 
@@ -88,10 +86,10 @@ class KeyNotFoundError(PystacheError):
         self.details = details
 
     def __str__(self):
-        return "Key %s not found: %s" % (repr(self.key), self.details)
+        return "Key {} not found: {}".format(repr(self.key), self.details)
 
 
-class ContextStack(object):
+class ContextStack:
 
     """
     Provides dictionary-like access to a stack of zero or more items.
@@ -140,7 +138,7 @@ class ContextStack(object):
         "ContextStack({'alpha': 'abc'}, {'numeric': 123})"
 
         """
-        return "%s%s" % (self.__class__.__name__, tuple(self._stack))
+        return "{}{}".format(self.__class__.__name__, tuple(self._stack))
 
     @staticmethod
     def create(*context, **kwargs):
diff --git a/python/pystache/pystache/defaults.py b/python/pystache/pystache/defaults.py
index bcfdf4cd3a..39c4c3b655 100644
--- a/python/pystache/pystache/defaults.py
+++ b/python/pystache/pystache/defaults.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module provides a central location for defining default behavior.
 
@@ -39,7 +37,7 @@ STRING_ENCODING = sys.getdefaultencoding()
 FILE_ENCODING = sys.getdefaultencoding()
 
 # The delimiters to start with when parsing.
-DELIMITERS = (u'{{', u'}}')
+DELIMITERS = ('{{', '}}')
 
 # How to handle missing tags when rendering a template.
 MISSING_TAGS = MissingTags.ignore
diff --git a/python/pystache/pystache/init.py b/python/pystache/pystache/init.py
index 38bb1f5a0e..72160475e3 100644
--- a/python/pystache/pystache/init.py
+++ b/python/pystache/pystache/init.py
@@ -1,5 +1,3 @@
-# encoding: utf-8
-
 """
 This module contains the initialization logic called by __init__.py.
 
diff --git a/python/pystache/pystache/loader.py b/python/pystache/pystache/loader.py
index d4a7e5310f..682d8511e1 100644
--- a/python/pystache/pystache/loader.py
+++ b/python/pystache/pystache/loader.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module provides a Loader class for locating and reading templates.
 
@@ -24,11 +22,11 @@ def _make_to_unicode():
         """
         if encoding is None:
             encoding = defaults.STRING_ENCODING
-        return unicode(s, encoding, defaults.DECODE_ERRORS)
+        return str(s, encoding, defaults.DECODE_ERRORS)
     return to_unicode
 
 
-class Loader(object):
+class Loader:
 
     """
     Loads the template associated to a name or user-defined object.
@@ -86,7 +84,7 @@ class Loader(object):
     def _make_locator(self):
         return Locator(extension=self.extension)
 
-    def unicode(self, s, encoding=None):
+    def str(self, s, encoding=None):
         """
         Convert a string to unicode using the given encoding, and return it.
 
@@ -104,8 +102,8 @@ class Loader(object):
             Defaults to None.
 
         """
-        if isinstance(s, unicode):
-            return unicode(s)
+        if isinstance(s, str):
+            return str(s)
 
         return self.to_unicode(s, encoding)
 
@@ -119,7 +117,7 @@ class Loader(object):
         if encoding is None:
             encoding = self.file_encoding
 
-        return self.unicode(b, encoding)
+        return self.str(b, encoding)
 
     def load_file(self, file_name):
         """
diff --git a/python/pystache/pystache/locator.py b/python/pystache/pystache/locator.py
index 30c5b01e01..a0df2887eb 100644
--- a/python/pystache/pystache/locator.py
+++ b/python/pystache/pystache/locator.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module provides a Locator class for finding template files.
 
@@ -13,7 +11,7 @@ from pystache.common import TemplateNotFoundError
 from pystache import defaults
 
 
-class Locator(object):
+class Locator:
 
     def __init__(self, extension=None):
         """
diff --git a/python/pystache/pystache/parsed.py b/python/pystache/pystache/parsed.py
index 372d96c666..3574dcbfa3 100644
--- a/python/pystache/pystache/parsed.py
+++ b/python/pystache/pystache/parsed.py
@@ -1,12 +1,10 @@
-# coding: utf-8
-
 """
 Exposes a class that represents a parsed (or compiled) template.
 
 """
 
 
-class ParsedTemplate(object):
+class ParsedTemplate:
 
     """
     Represents a parsed or compiled template.
@@ -41,10 +39,10 @@ class ParsedTemplate(object):
         """
         # We avoid use of the ternary operator for Python 2.4 support.
         def get_unicode(node):
-            if type(node) is unicode:
+            if type(node) is str:
                 return node
             return node.render(engine, context)
-        parts = map(get_unicode, self._parse_tree)
+        parts = list(map(get_unicode, self._parse_tree))
         s = ''.join(parts)
 
-        return unicode(s)
+        return str(s)
diff --git a/python/pystache/pystache/parser.py b/python/pystache/pystache/parser.py
index 9a4fba235b..6086db45b4 100644
--- a/python/pystache/pystache/parser.py
+++ b/python/pystache/pystache/parser.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 Exposes a parse() function to parse template strings.
 
@@ -11,8 +9,8 @@ from pystache import defaults
 from pystache.parsed import ParsedTemplate
 
 
-END_OF_LINE_CHARACTERS = [u'\r', u'\n']
-NON_BLANK_RE = re.compile(ur'^(.)', re.M)
+END_OF_LINE_CHARACTERS = ['\r', '\n']
+NON_BLANK_RE = re.compile(r'^(.)', re.M)
 
 
 # TODO: add some unit tests for this.
@@ -35,7 +33,7 @@ def parse(template, delimiters=None):
     ['Hey ', _SectionNode(key='who', index_begin=12, index_end=21, parsed=[_EscapeNode(key='name'), '!'])]
 
     """
-    if type(template) is not unicode:
+    if type(template) is not str:
         raise Exception("Template is not unicode: %s" % type(template))
     parser = _Parser(delimiters)
     return parser.parse(template)
@@ -94,7 +92,7 @@ class _CommentNode(object):
         return _format(self)
 
     def render(self, engine, context):
-        return u''
+        return ''
 
 
 class _ChangeNode(object):
@@ -106,7 +104,7 @@ class _ChangeNode(object):
         return _format(self)
 
     def render(self, engine, context):
-        return u''
+        return ''
 
 
 class _EscapeNode(object):
@@ -147,7 +145,7 @@ class _PartialNode(object):
     def render(self, engine, context):
         template = engine.resolve_partial(self.key)
         # Indent before rendering.
-        template = re.sub(NON_BLANK_RE, self.indent + ur'\1', template)
+        template = re.sub(NON_BLANK_RE, self.indent + r'\1', template)
 
         return engine.render(template, context)
 
@@ -168,7 +166,7 @@ class _InvertedNode(object):
         # Note that lambdas are considered truthy for inverted sections
         # per the spec.
         if data:
-            return u''
+            return ''
         return self.parsed_section.render(engine, context)
 
 
@@ -218,7 +216,7 @@ class _SectionNode(object):
             parts.append(self.parsed.render(engine, context))
             context.pop()
 
-        return unicode(''.join(parts))
+        return str(''.join(parts))
 
 
 class _Parser(object):
diff --git a/python/pystache/pystache/renderengine.py b/python/pystache/pystache/renderengine.py
index c797b1765a..926d81206d 100644
--- a/python/pystache/pystache/renderengine.py
+++ b/python/pystache/pystache/renderengine.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 Defines a class responsible for rendering logic.
 
@@ -19,7 +17,7 @@ def context_get(stack, name):
     return stack.get(name)
 
 
-class RenderEngine(object):
+class RenderEngine:
 
     """
     Provides a render() method.
@@ -160,7 +158,7 @@ class RenderEngine(object):
         if not is_string(val):
             # In case the template is an integer, for example.
             val = self.to_str(val)
-        if type(val) is not unicode:
+        if type(val) is not str:
             val = self.literal(val)
         return self.render(val, context, delimiters)
 
diff --git a/python/pystache/pystache/renderer.py b/python/pystache/pystache/renderer.py
index ff6a90c64b..3902a9e2bf 100644
--- a/python/pystache/pystache/renderer.py
+++ b/python/pystache/pystache/renderer.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module provides a Renderer class to render templates.
 
@@ -17,7 +15,7 @@ from pystache.specloader import SpecLoader
 from pystache.template_spec import TemplateSpec
 
 
-class Renderer(object):
+class Renderer:
 
     """
     A class for rendering mustache templates.
@@ -130,7 +128,7 @@ class Renderer(object):
         if string_encoding is None:
             string_encoding = defaults.STRING_ENCODING
 
-        if isinstance(search_dirs, basestring):
+        if isinstance(search_dirs, str):
             search_dirs = [search_dirs]
 
         self._context = None
@@ -177,16 +175,16 @@ class Renderer(object):
         """
         # We type-check to avoid "TypeError: decoding Unicode is not supported".
         # We avoid the Python ternary operator for Python 2.4 support.
-        if isinstance(s, unicode):
+        if isinstance(s, str):
             return s
-        return self.unicode(s)
+        return self.str(s)
 
     def _to_unicode_hard(self, s):
         """
         Convert a basestring to a string with type unicode (not subclass).
 
         """
-        return unicode(self._to_unicode_soft(s))
+        return str(self._to_unicode_soft(s))
 
     def _escape_to_unicode(self, s):
         """
@@ -195,9 +193,9 @@ class Renderer(object):
         Returns a unicode string (not subclass).
 
         """
-        return unicode(self.escape(self._to_unicode_soft(s)))
+        return str(self.escape(self._to_unicode_soft(s)))
 
-    def unicode(self, b, encoding=None):
+    def str(self, b, encoding=None):
         """
         Convert a byte string to unicode, using string_encoding and decode_errors.
 
@@ -222,7 +220,7 @@ class Renderer(object):
 
         # TODO: Wrap UnicodeDecodeErrors with a message about setting
         # the string_encoding and decode_errors attributes.
-        return unicode(b, encoding, self.decode_errors)
+        return str(b, encoding, self.decode_errors)
 
     def _make_loader(self):
         """
@@ -230,7 +228,7 @@ class Renderer(object):
 
         """
         return Loader(file_encoding=self.file_encoding, extension=self.file_extension,
-                      to_unicode=self.unicode, search_dirs=self.search_dirs)
+                      to_unicode=self.str, search_dirs=self.search_dirs)
 
     def _make_load_template(self):
         """
@@ -299,7 +297,7 @@ class Renderer(object):
             try:
                 return load_partial(name)
             except TemplateNotFoundError:
-                return u''
+                return ''
 
         return resolve_partial
 
@@ -316,7 +314,7 @@ class Renderer(object):
             try:
                 return context_get(stack, name)
             except KeyNotFoundError:
-                return u''
+                return ''
 
         return resolve_context
 
diff --git a/python/pystache/pystache/specloader.py b/python/pystache/pystache/specloader.py
index 3a77d4c528..a572e53460 100644
--- a/python/pystache/pystache/specloader.py
+++ b/python/pystache/pystache/specloader.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 This module supports customized (aka special or specified) template loading.
 
@@ -11,7 +9,7 @@ from pystache.loader import Loader
 
 
 # TODO: add test cases for this class.
-class SpecLoader(object):
+class SpecLoader:
 
     """
     Supports loading custom-specified templates (from TemplateSpec instances).
@@ -83,7 +81,7 @@ class SpecLoader(object):
 
         """
         if spec.template is not None:
-            return self.loader.unicode(spec.template, spec.template_encoding)
+            return self.loader.str(spec.template, spec.template_encoding)
 
         path = self._find(spec)
 
diff --git a/python/pystache/pystache/template_spec.py b/python/pystache/pystache/template_spec.py
index 9e9f454c19..f287961aac 100644
--- a/python/pystache/pystache/template_spec.py
+++ b/python/pystache/pystache/template_spec.py
@@ -1,5 +1,3 @@
-# coding: utf-8
-
 """
 Provides a class to customize template information on a per-view basis.
 
@@ -9,7 +7,7 @@ stands for "special" or "specified" template information.
 
 """
 
-class TemplateSpec(object):
+class TemplateSpec:
 
     """
     A mixin or interface for specifying custom template information.
diff --git a/python/pystache/setup.py b/python/pystache/setup.py
index 0d99aae8fb..83e8cd398f 100644
--- a/python/pystache/setup.py
+++ b/python/pystache/setup.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# coding: utf-8
 
 """
 This script supports publishing Pystache to PyPI.
@@ -85,6 +84,7 @@ Push a tag to GitHub:
 
 """
 
+from __future__ import print_function
 import os
 import shutil
 import sys
@@ -170,7 +170,7 @@ def write(u, path):
     Write a unicode string to a file (as utf-8).
 
     """
-    print("writing to: %s" % path)
+    print(("writing to: %s" % path))
     # This function implementation was chosen to be compatible across Python 2/3.
     f = open(path, "wb")
     try:
@@ -200,7 +200,7 @@ def strip_html_comments(text):
     lines = text.splitlines(True)  # preserve line endings.
 
     # Remove HTML comments (which we only allow to take a special form).
-    new_lines = filter(lambda line: not line.startswith("%s" % (md_path, rst_temp_path,
-                                                       command))
+    command = "pandoc --write=rst --output={} {}".format(rst_temp_path, md_path)
+    print(("converting with pandoc: {} to {}\n-->{}".format(md_path, rst_temp_path,
+                                                       command)))
 
     if os.path.exists(rst_temp_path):
         os.remove(rst_temp_path)
@@ -290,17 +290,17 @@ def publish():
     long_description = make_long_description()
 
     if long_description != read(RST_DESCRIPTION_PATH):
-        print("""\
-Description file not up-to-date: %s
+        print(("""\
+Description file not up-to-date: {}
 Run the following command and commit the changes--
 
-    python setup.py %s
-""" % (RST_DESCRIPTION_PATH, PREP_COMMAND))
+    python setup.py {}
+""".format(RST_DESCRIPTION_PATH, PREP_COMMAND)))
         sys.exit()
 
-    print("Description up-to-date: %s" % RST_DESCRIPTION_PATH)
+    print(("Description up-to-date: %s" % RST_DESCRIPTION_PATH))
 
-    answer = raw_input("Are you sure you want to publish to PyPI (yes/no)?")
+    answer = input("Are you sure you want to publish to PyPI (yes/no)?")
 
     if answer != "yes":
         exit("Aborted: nothing published")
@@ -365,7 +365,7 @@ def main(sys_argv):
 
     # TODO: use the logging module instead of printing.
     # TODO: include the following in a verbose mode.
-    sys.stderr.write("pystache: using: version %s of %s\n" % (repr(dist.__version__), repr(dist)))
+    sys.stderr.write("pystache: using: version {} of {}\n".format(repr(dist.__version__), repr(dist)))
 
     command = sys_argv[-1]
 
diff --git a/python/pystache/test_pystache.py b/python/pystache/test_pystache.py
index 9a1a3ca26d..dc99f06ee8 100644
--- a/python/pystache/test_pystache.py
+++ b/python/pystache/test_pystache.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# coding: utf-8
 
 """
 Runs project tests.
diff --git a/python/pytest/_pytest/_argcomplete.py b/python/pytest/_pytest/_argcomplete.py
index 955855a964..58bccb66b9 100644
--- a/python/pytest/_pytest/_argcomplete.py
+++ b/python/pytest/_pytest/_argcomplete.py
@@ -1,4 +1,3 @@
-
 """allow bash-completion for argparse with argcomplete if installed
 needs argcomplete>=0.5.6 for python 3.2/3.3 (older versions fail
 to find the magic string, so _ARGCOMPLETE env. var is never set, and
diff --git a/python/pytest/_pytest/_code/_py2traceback.py b/python/pytest/_pytest/_code/_py2traceback.py
index a830d9899a..2661738c10 100644
--- a/python/pytest/_pytest/_code/_py2traceback.py
+++ b/python/pytest/_pytest/_code/_py2traceback.py
@@ -23,7 +23,7 @@ def format_exception_only(etype, value):
 
     # An instance should not have a meaningful value parameter, but
     # sometimes does, particularly for string exceptions, such as
-    # >>> raise string1, string2  # deprecated
+    # >>> raise string1(string2  # deprecated)
     #
     # Clear these out first because issubtype(string1, SyntaxError)
     # would throw another exception and mask the original problem.
@@ -49,7 +49,7 @@ def format_exception_only(etype, value):
         if badline is not None:
             if isinstance(badline, bytes):  # python 2 only
                 badline = badline.decode('utf-8', 'replace')
-            lines.append(u'    %s\n' % badline.strip())
+            lines.append('    %s\n' % badline.strip())
             if offset is not None:
                 caretspace = badline.rstrip('\n')[:offset].lstrip()
                 # non-space whitespace (likes tabs) must be kept for alignment
@@ -67,12 +67,12 @@ def _format_final_exc_line(etype, value):
     if value is None or not valuestr:
         line = "%s\n" % etype
     else:
-        line = "%s: %s\n" % (etype, valuestr)
+        line = "{}: {}\n".format(etype, valuestr)
     return line
 
 def _some_str(value):
     try:
-        return unicode(value)
+        return str(value)
     except Exception:
         try:
             return str(value)
diff --git a/python/pytest/_pytest/_code/code.py b/python/pytest/_pytest/_code/code.py
index 8995cc1f71..1f0b3bd355 100644
--- a/python/pytest/_pytest/_code/code.py
+++ b/python/pytest/_pytest/_code/code.py
@@ -7,12 +7,9 @@ builtin_repr = repr
 
 reprlib = py.builtin._tryimport('repr', 'reprlib')
 
-if sys.version_info[0] >= 3:
-    from traceback import format_exception_only
-else:
-    from ._py2traceback import format_exception_only
+from traceback import format_exception_only
 
-class Code(object):
+class Code:
     """ wrapper around Python code objects """
     def __init__(self, rawcode):
         if not hasattr(rawcode, "co_filename"):
@@ -72,7 +69,7 @@ class Code(object):
             argcount += raw.co_flags & CO_VARKEYWORDS
         return raw.co_varnames[:argcount]
 
-class Frame(object):
+class Frame:
     """Wrapper around a Python frame holding f_locals and f_globals
     in which expressions can be evaluated."""
 
@@ -133,7 +130,7 @@ class Frame(object):
                 pass     # this can occur when using Psyco
         return retval
 
-class TracebackEntry(object):
+class TracebackEntry:
     """ a single entry in a traceback """
 
     _repr_style = None
@@ -182,7 +179,7 @@ class TracebackEntry(object):
             source = py.builtin._totext(self.statement).strip()
             x = reinterpret(source, self.frame, should_fail=True)
             if not py.builtin._istext(x):
-                raise TypeError("interpret returned non-string %r" % (x,))
+                raise TypeError("interpret returned non-string {!r}".format(x))
             self.exprinfo = x
         return self.exprinfo
 
@@ -286,7 +283,7 @@ class Traceback(list):
         return self
 
     def __getitem__(self, key):
-        val = super(Traceback, self).__getitem__(key)
+        val = super().__getitem__(key)
         if isinstance(key, type(slice(0))):
             val = self.__class__(val)
         return val
@@ -301,7 +298,7 @@ class Traceback(list):
             by default this removes all the TracebackEntries which are hidden
             (see ishidden() above)
         """
-        return Traceback(filter(fn, self))
+        return Traceback(list(filter(fn, self)))
 
     def getcrashentry(self):
         """ return last non-hidden traceback entry that lead
@@ -340,7 +337,7 @@ class Traceback(list):
 co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2',
                    '?', 'eval')
 
-class ExceptionInfo(object):
+class ExceptionInfo:
     """ wraps sys.exc_info() objects and offers
         help for navigating the traceback.
     """
@@ -425,10 +422,10 @@ class ExceptionInfo(object):
     def __unicode__(self):
         entry = self.traceback[-1]
         loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
-        return unicode(loc)
+        return str(loc)
 
 
-class FormattedExcinfo(object):
+class FormattedExcinfo:
     """ presenting information about failing Functions and Generators. """
     # for traceback entries
     flow_marker = ">"
@@ -703,7 +700,7 @@ class ReprEntry(TerminalRepr):
             self.reprfileloc.toterminal(tw)
 
     def __str__(self):
-        return "%s\n%s\n%s" % ("\n".join(self.lines),
+        return "{}\n{}\n{}".format("\n".join(self.lines),
                                self.reprlocals,
                                self.reprfileloc)
 
diff --git a/python/pytest/_pytest/_code/source.py b/python/pytest/_pytest/_code/source.py
index a1521f8a21..36ba5bc9d2 100644
--- a/python/pytest/_pytest/_code/source.py
+++ b/python/pytest/_pytest/_code/source.py
@@ -1,5 +1,3 @@
-from __future__ import generators
-
 from bisect import bisect_right
 import sys
 import inspect, tokenize
@@ -15,7 +13,7 @@ except ImportError:
     _ast = None
 
 
-class Source(object):
+class Source:
     """ a immutable object holding a source code fragment,
         possibly deindenting it.
     """
@@ -193,14 +191,13 @@ class Source(object):
             if flag & _AST_FLAG:
                 return co
             lines = [(x + "\n") for x in self.lines]
-            if sys.version_info[0] >= 3:
-                # XXX py3's inspect.getsourcefile() checks for a module
-                # and a pep302 __loader__ ... we don't have a module
-                # at code compile-time so we need to fake it here
-                m = ModuleType("_pycodecompile_pseudo_module")
-                py.std.inspect.modulesbyfile[filename] = None
-                py.std.sys.modules[None] = m
-                m.__loader__ = 1
+            # XXX py3's inspect.getsourcefile() checks for a module
+            # and a pep302 __loader__ ... we don't have a module
+            # at code compile-time so we need to fake it here
+            m = ModuleType("_pycodecompile_pseudo_module")
+            py.std.inspect.modulesbyfile[filename] = None
+            py.std.sys.modules[None] = m
+            m.__loader__ = 1
             py.std.linecache.cache[filename] = (1, None, lines, filename)
             return co
 
@@ -243,7 +240,7 @@ def getfslineno(obj):
         if fspath:
             try:
                 _, lineno = findsource(obj)
-            except IOError:
+            except OSError:
                 pass
     else:
         fspath = code.path
diff --git a/python/pytest/_pytest/assertion/__init__.py b/python/pytest/_pytest/assertion/__init__.py
index 6921deb2a6..67cefa8d07 100644
--- a/python/pytest/_pytest/assertion/__init__.py
+++ b/python/pytest/_pytest/assertion/__init__.py
@@ -70,7 +70,7 @@ def pytest_configure(config):
     warn_about_missing_assertion(mode)
     config._assertstate = AssertionState(config, mode)
     config._assertstate.hook = hook
-    config._assertstate.trace("configured with mode set to %r" % (mode,))
+    config._assertstate.trace("configured with mode set to {!r}".format(mode))
     def undo():
         hook = config._assertstate.hook
         if hook is not None and hook in sys.meta_path:
diff --git a/python/pytest/_pytest/assertion/reinterpret.py b/python/pytest/_pytest/assertion/reinterpret.py
index f4262c3ace..7615c1bcf7 100644
--- a/python/pytest/_pytest/assertion/reinterpret.py
+++ b/python/pytest/_pytest/assertion/reinterpret.py
@@ -49,8 +49,7 @@ class AssertionError(util.BuiltinAssertionError):
             if not self.args:
                 self.args = (self.msg,)
 
-if sys.version_info > (3, 0):
-    AssertionError.__module__ = "builtins"
+AssertionError.__module__ = "builtins"
 
 if sys.platform.startswith("java"):
     # See http://bugs.jython.org/issue1497
@@ -62,8 +61,8 @@ if sys.platform.startswith("java"):
               "AugAssign", "Print", "For", "While", "If", "With", "Raise",
               "TryExcept", "TryFinally", "Assert", "Import", "ImportFrom",
               "Exec", "Global", "Expr", "Pass", "Break", "Continue")
-    _expr_nodes = set(getattr(ast, name) for name in _exprs)
-    _stmt_nodes = set(getattr(ast, name) for name in _stmts)
+    _expr_nodes = {getattr(ast, name) for name in _exprs}
+    _stmt_nodes = {getattr(ast, name) for name in _stmts}
     def _is_ast_expr(node):
         return node.__class__ in _expr_nodes
     def _is_ast_stmt(node):
@@ -78,7 +77,7 @@ try:
     _Starred = ast.Starred
 except AttributeError:
     # Python 2. Define a dummy class so isinstance() will always be False.
-    class _Starred(object): pass
+    class _Starred: pass
 
 
 class Failure(Exception):
@@ -112,9 +111,9 @@ def getfailure(e):
     value = e.cause[1]
     if str(value):
         lines = explanation.split('\n')
-        lines[0] += "  << %s" % (value,)
+        lines[0] += "  << {}".format(value)
         explanation = '\n'.join(lines)
-    text = "%s: %s" % (e.cause[0].__name__, explanation)
+    text = "{}: {}".format(e.cause[0].__name__, explanation)
     if text.startswith('AssertionError: assert '):
         text = text[16:]
     return text
@@ -193,7 +192,7 @@ class DebugInterpreter(ast.NodeVisitor):
     def visit_Name(self, name):
         explanation, result = self.generic_visit(name)
         # See if the name is local.
-        source = "%r in locals() is not globals()" % (name.id,)
+        source = "{!r} in locals() is not globals()".format(name.id)
         co = self._compile(source)
         try:
             local = self.frame.eval(co)
@@ -210,9 +209,9 @@ class DebugInterpreter(ast.NodeVisitor):
         for op, next_op in zip(comp.ops, comp.comparators):
             next_explanation, next_result = self.visit(next_op)
             op_symbol = operator_map[op.__class__]
-            explanation = "%s %s %s" % (left_explanation, op_symbol,
+            explanation = "{} {} {}".format(left_explanation, op_symbol,
                                         next_explanation)
-            source = "__exprinfo_left %s __exprinfo_right" % (op_symbol,)
+            source = "__exprinfo_left {} __exprinfo_right".format(op_symbol)
             co = self._compile(source)
             try:
                 result = self.frame.eval(co, __exprinfo_left=left_result,
@@ -261,9 +260,9 @@ class DebugInterpreter(ast.NodeVisitor):
         left_explanation, left_result = self.visit(binop.left)
         right_explanation, right_result = self.visit(binop.right)
         symbol = operator_map[binop.op.__class__]
-        explanation = "(%s %s %s)" % (left_explanation, symbol,
+        explanation = "({} {} {})".format(left_explanation, symbol,
                                       right_explanation)
-        source = "__exprinfo_left %s __exprinfo_right" % (symbol,)
+        source = "__exprinfo_left {} __exprinfo_right".format(symbol)
         co = self._compile(source)
         try:
             result = self.frame.eval(co, __exprinfo_left=left_result,
@@ -282,24 +281,24 @@ class DebugInterpreter(ast.NodeVisitor):
             if isinstance(arg, _Starred):
                 arg_name = "__exprinfo_star"
                 ns[arg_name] = arg_result
-                arguments.append("*%s" % (arg_name,))
-                arg_explanations.append("*%s" % (arg_explanation,))
+                arguments.append("*{}".format(arg_name))
+                arg_explanations.append("*{}".format(arg_explanation))
             else:
-                arg_name = "__exprinfo_%s" % (len(ns),)
+                arg_name = "__exprinfo_{}".format(len(ns))
                 ns[arg_name] = arg_result
                 arguments.append(arg_name)
                 arg_explanations.append(arg_explanation)
         for keyword in call.keywords:
             arg_explanation, arg_result = self.visit(keyword.value)
             if keyword.arg:
-                arg_name = "__exprinfo_%s" % (len(ns),)
+                arg_name = "__exprinfo_{}".format(len(ns))
                 keyword_source = "%s=%%s" % (keyword.arg)
                 arguments.append(keyword_source % (arg_name,))
                 arg_explanations.append(keyword_source % (arg_explanation,))
             else:
                 arg_name = "__exprinfo_kwds"
-                arguments.append("**%s" % (arg_name,))
-                arg_explanations.append("**%s" % (arg_explanation,))
+                arguments.append("**{}".format(arg_name))
+                arg_explanations.append("**{}".format(arg_explanation))
 
             ns[arg_name] = arg_result
 
@@ -307,19 +306,19 @@ class DebugInterpreter(ast.NodeVisitor):
             arg_explanation, arg_result = self.visit(call.starargs)
             arg_name = "__exprinfo_star"
             ns[arg_name] = arg_result
-            arguments.append("*%s" % (arg_name,))
-            arg_explanations.append("*%s" % (arg_explanation,))
+            arguments.append("*{}".format(arg_name))
+            arg_explanations.append("*{}".format(arg_explanation))
 
         if getattr(call, 'kwargs', None):
             arg_explanation, arg_result = self.visit(call.kwargs)
             arg_name = "__exprinfo_kwds"
             ns[arg_name] = arg_result
-            arguments.append("**%s" % (arg_name,))
-            arg_explanations.append("**%s" % (arg_explanation,))
+            arguments.append("**{}".format(arg_name))
+            arg_explanations.append("**{}".format(arg_explanation))
         args_explained = ", ".join(arg_explanations)
-        explanation = "%s(%s)" % (func_explanation, args_explained)
+        explanation = "{}({})".format(func_explanation, args_explained)
         args = ", ".join(arguments)
-        source = "__exprinfo_func(%s)" % (args,)
+        source = "__exprinfo_func({})".format(args)
         co = self._compile(source)
         try:
             result = self.frame.eval(co, **ns)
@@ -343,8 +342,8 @@ class DebugInterpreter(ast.NodeVisitor):
         if not isinstance(attr.ctx, ast.Load):
             return self.generic_visit(attr)
         source_explanation, source_result = self.visit(attr.value)
-        explanation = "%s.%s" % (source_explanation, attr.attr)
-        source = "__exprinfo_expr.%s" % (attr.attr,)
+        explanation = "{}.{}".format(source_explanation, attr.attr)
+        source = "__exprinfo_expr.{}".format(attr.attr)
         co = self._compile(source)
         try:
             try:
@@ -357,12 +356,12 @@ class DebugInterpreter(ast.NodeVisitor):
                 co = self._compile(source)
                 class_name = self.frame.eval(co, __exprinfo_expr=source_result)
                 mangled_attr = "_" + class_name +  attr.attr
-                source = "__exprinfo_expr.%s" % (mangled_attr,)
+                source = "__exprinfo_expr.{}".format(mangled_attr)
                 co = self._compile(source)
                 result = self.frame.eval(co, __exprinfo_expr=source_result)
         except Exception:
             raise Failure(explanation)
-        explanation = "%s\n{%s = %s.%s\n}" % (self.frame.repr(result),
+        explanation = "{}\n{{{} = {}.{}\n}}".format(self.frame.repr(result),
                                               self.frame.repr(result),
                                               source_explanation, attr.attr)
         # Check if the attr is from an instance.
@@ -381,7 +380,7 @@ class DebugInterpreter(ast.NodeVisitor):
 
     def visit_Assert(self, assrt):
         test_explanation, test_result = self.visit(assrt.test)
-        explanation = "assert %s" % (test_explanation,)
+        explanation = "assert {}".format(test_explanation)
         if not self.frame.is_true(test_result):
             try:
                 raise util.BuiltinAssertionError
@@ -391,7 +390,7 @@ class DebugInterpreter(ast.NodeVisitor):
 
     def visit_Assign(self, assign):
         value_explanation, value_result = self.visit(assign.value)
-        explanation = "... = %s" % (value_explanation,)
+        explanation = "... = {}".format(value_explanation)
         name = ast.Name("__exprinfo_expr", ast.Load(),
                         lineno=assign.value.lineno,
                         col_offset=assign.value.col_offset)
diff --git a/python/pytest/_pytest/assertion/rewrite.py b/python/pytest/_pytest/assertion/rewrite.py
index 14b8e49db2..8275fe997e 100644
--- a/python/pytest/_pytest/assertion/rewrite.py
+++ b/python/pytest/_pytest/assertion/rewrite.py
@@ -26,7 +26,7 @@ else:
     else:
         impl = "cpython"
     ver = sys.version_info
-    PYTEST_TAG = "%s-%s%s-PYTEST" % (impl, ver[0], ver[1])
+    PYTEST_TAG = "{}-{}{}-PYTEST".format(impl, ver[0], ver[1])
     del ver, impl
 
 PYC_EXT = ".py" + (__debug__ and "c" or "o")
@@ -41,7 +41,7 @@ else:
     ast_Call = lambda a,b,c: ast.Call(a, b, c, None, None)
 
 
-class AssertionRewritingHook(object):
+class AssertionRewritingHook:
     """PEP302 Import hook which rewrites asserts."""
 
     def __init__(self):
@@ -95,7 +95,7 @@ class AssertionRewritingHook(object):
             try:
                 for pat in self.fnpats:
                     if fn_pypath.fnmatch(pat):
-                        state.trace("matched test file %r" % (fn,))
+                        state.trace("matched test file {!r}".format(fn))
                         break
                 else:
                     return None
@@ -139,7 +139,7 @@ class AssertionRewritingHook(object):
         # to check for a cached pyc. This may not be optimal...
         co = _read_pyc(fn_pypath, pyc, state.trace)
         if co is None:
-            state.trace("rewriting %r" % (fn,))
+            state.trace("rewriting {!r}".format(fn))
             source_stat, co = _rewrite_test(state, fn_pypath)
             if co is None:
                 # Probably a SyntaxError in the test.
@@ -147,7 +147,7 @@ class AssertionRewritingHook(object):
             if write:
                 _make_rewritten_pyc(state, source_stat, pyc, co)
         else:
-            state.trace("found cached rewritten pyc for %r" % (fn,))
+            state.trace("found cached rewritten pyc for {!r}".format(fn))
         self.modules[name] = co, pyc
         return self
 
@@ -218,7 +218,7 @@ def _write_pyc(state, co, source_stat, pyc):
     # the comment in load_module above.)
     try:
         fp = open(pyc, "wb")
-    except IOError:
+    except OSError:
         err = sys.exc_info()[1].errno
         state.trace("error writing pyc file at %s: errno=%s" %(pyc, err))
         # we ignore any failure to write the cache file
@@ -235,8 +235,8 @@ def _write_pyc(state, co, source_stat, pyc):
         fp.close()
     return True
 
-RN = "\r\n".encode("utf-8")
-N = "\n".encode("utf-8")
+RN = b"\r\n"
+N = b"\n"
 
 cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+")
 BOM_UTF8 = '\xef\xbb\xbf'
@@ -246,7 +246,7 @@ def _rewrite_test(state, fn):
     try:
         stat = fn.stat()
         source = fn.read("rb")
-    except EnvironmentError:
+    except OSError:
         return None, None
     if ASCII_IS_DEFAULT_ENCODING:
         # ASCII is the default encoding in Python 2. Without a coding
@@ -285,7 +285,7 @@ def _rewrite_test(state, fn):
         tree = ast.parse(source)
     except SyntaxError:
         # Let this pop up again in the real import.
-        state.trace("failed to parse: %r" % (fn,))
+        state.trace("failed to parse: {!r}".format(fn))
         return None, None
     rewrite_asserts(tree)
     try:
@@ -293,7 +293,7 @@ def _rewrite_test(state, fn):
     except SyntaxError:
         # It's possible that this error is from some bug in the
         # assertion rewriting, but I don't know of a fast way to tell.
-        state.trace("failed to compile: %r" % (fn,))
+        state.trace("failed to compile: {!r}".format(fn))
         return None, None
     return stat, co
 
@@ -317,15 +317,15 @@ def _read_pyc(source, pyc, trace=lambda x: None):
     """
     try:
         fp = open(pyc, "rb")
-    except IOError:
+    except OSError:
         return None
     with fp:
         try:
             mtime = int(source.mtime())
             size = source.size()
             data = fp.read(12)
-        except EnvironmentError as e:
-            trace('_read_pyc(%s): EnvironmentError %s' % (source, e))
+        except OSError as e:
+            trace('_read_pyc({}): EnvironmentError {}'.format(source, e))
             return None
         # Check for invalid or out of date pyc file.
         if (len(data) != 12 or data[:4] != imp.get_magic() or
@@ -335,7 +335,7 @@ def _read_pyc(source, pyc, trace=lambda x: None):
         try:
             co = marshal.load(fp)
         except Exception as e:
-            trace('_read_pyc(%s): marshal.load error %s' % (source, e))
+            trace('_read_pyc({}): marshal.load error {}'.format(source, e))
             return None
         if not isinstance(co, types.CodeType):
             trace('_read_pyc(%s): not a code object' % source)
@@ -408,7 +408,7 @@ def _format_boolop(explanations, is_or):
     return explanation.replace(t('%'), t('%%'))
 
 def _call_reprcompare(ops, results, expls, each_obj):
-    for i, res, expl in zip(range(len(ops)), results, expls):
+    for i, res, expl in zip(list(range(len(ops))), results, expls):
         try:
             done = not res
         except Exception:
@@ -695,10 +695,7 @@ class AssertionRewriter(ast.NodeVisitor):
         fmt = self.helper("format_explanation", msg)
         err_name = ast.Name("AssertionError", ast.Load())
         exc = ast_Call(err_name, [fmt], [])
-        if sys.version_info[0] >= 3:
-            raise_ = ast.Raise(exc, None)
-        else:
-            raise_ = ast.Raise(exc, None, None)
+        raise_ = ast.Raise(exc, None)
         body.append(raise_)
         # Clear temporary variables by setting them to None.
         if self.variables:
@@ -766,7 +763,7 @@ class AssertionRewriter(ast.NodeVisitor):
         symbol = binop_map[binop.op.__class__]
         left_expr, left_expl = self.visit(binop.left)
         right_expr, right_expl = self.visit(binop.right)
-        explanation = "(%s %s %s)" % (left_expl, symbol, right_expl)
+        explanation = "({} {} {})".format(left_expl, symbol, right_expl)
         res = self.assign(ast.BinOp(left_expr, binop.op, right_expr))
         return res, explanation
 
@@ -790,11 +787,11 @@ class AssertionRewriter(ast.NodeVisitor):
             else: ## **args have `arg` keywords with an .arg of None
                 arg_expls.append("**" + expl)
 
-        expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
+        expl = "{}({})".format(func_expl, ', '.join(arg_expls))
         new_call = ast.Call(new_func, new_args, new_kwargs)
         res = self.assign(new_call)
         res_expl = self.explanation_param(self.display(res))
-        outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
+        outer_expl = "{}\n{{{} = {}\n}}".format(res_expl, res_expl, expl)
         return res, outer_expl
 
     def visit_Starred(self, starred):
@@ -825,12 +822,12 @@ class AssertionRewriter(ast.NodeVisitor):
         if call.kwargs:
             new_kwarg, expl = self.visit(call.kwargs)
             arg_expls.append("**" + expl)
-        expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
+        expl = "{}({})".format(func_expl, ', '.join(arg_expls))
         new_call = ast.Call(new_func, new_args, new_kwargs,
                             new_star, new_kwarg)
         res = self.assign(new_call)
         res_expl = self.explanation_param(self.display(res))
-        outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
+        outer_expl = "{}\n{{{} = {}\n}}".format(res_expl, res_expl, expl)
         return res, outer_expl
 
     # ast.Call signature changed on 3.5,
@@ -858,7 +855,7 @@ class AssertionRewriter(ast.NodeVisitor):
         res_variables = [self.variable() for i in range(len(comp.ops))]
         load_names = [ast.Name(v, ast.Load()) for v in res_variables]
         store_names = [ast.Name(v, ast.Store()) for v in res_variables]
-        it = zip(range(len(comp.ops)), comp.ops, comp.comparators)
+        it = list(zip(list(range(len(comp.ops))), comp.ops, comp.comparators))
         expls = []
         syms = []
         results = [left_res]
@@ -867,7 +864,7 @@ class AssertionRewriter(ast.NodeVisitor):
             results.append(next_res)
             sym = binop_map[op.__class__]
             syms.append(ast.Str(sym))
-            expl = "%s %s %s" % (left_expl, sym, next_expl)
+            expl = "{} {} {}".format(left_expl, sym, next_expl)
             expls.append(ast.Str(expl))
             res_expr = ast.Compare(left_res, [op], [next_res])
             self.statements.append(ast.Assign([store_names[i]], res_expr))
diff --git a/python/pytest/_pytest/assertion/util.py b/python/pytest/_pytest/assertion/util.py
index f2f23efea2..d384d804b3 100644
--- a/python/pytest/_pytest/assertion/util.py
+++ b/python/pytest/_pytest/assertion/util.py
@@ -4,7 +4,7 @@ import pprint
 import _pytest._code
 import py
 try:
-    from collections import Sequence
+    from collections.abc import Sequence
 except ImportError:
     Sequence = list
 
@@ -66,7 +66,7 @@ def _collapse_false(explanation):
                     break
             prev_c = c
         else:
-            raise AssertionError("unbalanced braces: %r" % (explanation,))
+            raise AssertionError("unbalanced braces: {!r}".format(explanation))
         end = start + i
         where = end
         if explanation[end - 1] == '\n':
@@ -130,9 +130,9 @@ def _format_lines(lines):
 
 # Provide basestring in python3
 try:
-    basestring = basestring
+    str = str
 except NameError:
-    basestring = str
+    str = str
 
 
 def assertrepr_compare(config, op, left, right):
@@ -144,8 +144,8 @@ def assertrepr_compare(config, op, left, right):
     summary = u('%s %s %s') % (ecu(left_repr), op, ecu(right_repr))
 
     issequence = lambda x: (isinstance(x, (list, tuple, Sequence)) and
-                            not isinstance(x, basestring))
-    istext = lambda x: isinstance(x, basestring)
+                            not isinstance(x, str))
+    istext = lambda x: isinstance(x, str)
     isdict = lambda x: isinstance(x, dict)
     isset = lambda x: isinstance(x, (set, frozenset))
 
@@ -287,14 +287,14 @@ def _compare_eq_set(left, right, verbose=False):
 def _compare_eq_dict(left, right, verbose=False):
     explanation = []
     common = set(left).intersection(set(right))
-    same = dict((k, left[k]) for k in common if left[k] == right[k])
+    same = {k: left[k] for k in common if left[k] == right[k]}
     if same and not verbose:
         explanation += [u('Omitting %s identical items, use -v to show') %
                         len(same)]
     elif same:
         explanation += [u('Common items:')]
         explanation += pprint.pformat(same).splitlines()
-    diff = set(k for k in common if left[k] != right[k])
+    diff = {k for k in common if left[k] != right[k]}
     if diff:
         explanation += [u('Differing items:')]
         for k in diff:
@@ -304,12 +304,12 @@ def _compare_eq_dict(left, right, verbose=False):
     if extra_left:
         explanation.append(u('Left contains more items:'))
         explanation.extend(pprint.pformat(
-            dict((k, left[k]) for k in extra_left)).splitlines())
+            {k: left[k] for k in extra_left}).splitlines())
     extra_right = set(right) - set(left)
     if extra_right:
         explanation.append(u('Right contains more items:'))
         explanation.extend(pprint.pformat(
-            dict((k, right[k]) for k in extra_right)).splitlines())
+            {k: right[k] for k in extra_right}).splitlines())
     return explanation
 
 
diff --git a/python/pytest/_pytest/cacheprovider.py b/python/pytest/_pytest/cacheprovider.py
index 0657001f2d..0606673060 100755
--- a/python/pytest/_pytest/cacheprovider.py
+++ b/python/pytest/_pytest/cacheprovider.py
@@ -11,7 +11,7 @@ import json
 from os.path import sep as _sep, altsep as _altsep
 
 
-class Cache(object):
+class Cache:
     def __init__(self, config):
         self.config = config
         self._cachedir = config.rootdir.join(".cache")
@@ -56,7 +56,7 @@ class Cache(object):
                 with path.open("r") as f:
                     return json.load(f)
             except ValueError:
-                self.trace("cache-invalid at %s" % (path,))
+                self.trace("cache-invalid at {}".format(path))
         return default
 
     def set(self, key, value):
@@ -73,17 +73,17 @@ class Cache(object):
             path.dirpath().ensure_dir()
         except (py.error.EEXIST, py.error.EACCES):
             self.config.warn(
-                code='I9', message='could not create cache path %s' % (path,)
+                code='I9', message='could not create cache path {}'.format(path)
             )
             return
         try:
             f = path.open('w')
         except py.error.ENOTDIR:
             self.config.warn(
-                code='I9', message='cache could not write path %s' % (path,))
+                code='I9', message='cache could not write path {}'.format(path))
         else:
             with f:
-                self.trace("cache-write %s: %r" % (key, value,))
+                self.trace("cache-write {}: {!r}".format(key, value))
                 json.dump(value, f, indent=2, sort_keys=True)
 
 
diff --git a/python/pytest/_pytest/capture.py b/python/pytest/_pytest/capture.py
index 3895a714aa..3b93f25c88 100644
--- a/python/pytest/_pytest/capture.py
+++ b/python/pytest/_pytest/capture.py
@@ -2,7 +2,6 @@
 per-test stdout/stderr capturing mechanism.
 
 """
-from __future__ import with_statement
 
 import sys
 import os
@@ -12,7 +11,7 @@ import py
 import pytest
 
 from py.io import TextIO
-unicode = py.builtin.text
+str = py.builtin.text
 
 patchsysdict = {0: 'stdin', 1: 'stdout', 2: 'stderr'}
 
@@ -220,14 +219,14 @@ def safe_text_dupfile(f, mode, default_encoding="UTF8"):
     return EncodedFile(f, encoding or default_encoding)
 
 
-class EncodedFile(object):
+class EncodedFile:
     errors = "strict"  # possibly needed by py3 code (issue555)
     def __init__(self, buffer, encoding):
         self.buffer = buffer
         self.encoding = encoding
 
     def write(self, obj):
-        if isinstance(obj, unicode):
+        if isinstance(obj, str):
             obj = obj.encode(self.encoding, "replace")
         self.buffer.write(obj)
 
@@ -239,7 +238,7 @@ class EncodedFile(object):
         return getattr(object.__getattribute__(self, "buffer"), name)
 
 
-class MultiCapture(object):
+class MultiCapture:
     out = err = in_ = None
 
     def __init__(self, out=True, err=True, in_=True, Capture=None):
@@ -318,7 +317,7 @@ class FDCapture:
         else:
             if targetfd == 0:
                 assert not tmpfile, "cannot set tmpfile with stdin"
-                tmpfile = open(os.devnull, "r")
+                tmpfile = open(os.devnull)
                 self.syscapture = SysCapture(targetfd)
             else:
                 if tmpfile is None:
@@ -333,7 +332,7 @@ class FDCapture:
             self.tmpfile_fd = tmpfile.fileno()
 
     def __repr__(self):
-        return "" % (self.targetfd, self.targetfd_save)
+        return "".format(self.targetfd, self.targetfd_save)
 
     def start(self):
         """ Start capturing on targetfd using memorized tmpfile. """
@@ -430,7 +429,7 @@ class DontReadFromInput:
     encoding = None
 
     def read(self, *args):
-        raise IOError("reading from stdin while output is captured")
+        raise OSError("reading from stdin while output is captured")
     readline = read
     readlines = read
     __iter__ = read
diff --git a/python/pytest/_pytest/config.py b/python/pytest/_pytest/config.py
index 9a308df2bb..a83781d7d5 100644
--- a/python/pytest/_pytest/config.py
+++ b/python/pytest/_pytest/config.py
@@ -103,7 +103,7 @@ def _prepareconfig(args=None, plugins=None):
         args = [str(args)]
     elif not isinstance(args, (tuple, list)):
         if not isinstance(args, str):
-            raise ValueError("not a string or argument list: %r" % (args,))
+            raise ValueError("not a string or argument list: {!r}".format(args))
         args = shlex.split(args, posix=sys.platform != "win32")
     config = get_config()
     pluginmanager = config.pluginmanager
@@ -131,7 +131,7 @@ class PytestPluginManager(PluginManager):
     * ``conftest.py`` loading during start-up;
     """
     def __init__(self):
-        super(PytestPluginManager, self).__init__("pytest", implprefix="pytest_")
+        super().__init__("pytest", implprefix="pytest_")
         self._conftest_plugins = set()
 
         # state related to local conftest plugins
@@ -177,14 +177,14 @@ class PytestPluginManager(PluginManager):
             return
 
         method = getattr(plugin, name)
-        opts = super(PytestPluginManager, self).parse_hookimpl_opts(plugin, name)
+        opts = super().parse_hookimpl_opts(plugin, name)
         if opts is not None:
             for name in ("tryfirst", "trylast", "optionalhook", "hookwrapper"):
                 opts.setdefault(name, hasattr(method, name))
         return opts
 
     def parse_hookspec_opts(self, module_or_class, name):
-        opts = super(PytestPluginManager, self).parse_hookspec_opts(
+        opts = super().parse_hookspec_opts(
                                                 module_or_class, name)
         if opts is None:
             method = getattr(module_or_class, name)
@@ -194,7 +194,7 @@ class PytestPluginManager(PluginManager):
         return opts
 
     def _verify_hook(self, hook, hookmethod):
-        super(PytestPluginManager, self)._verify_hook(hook, hookmethod)
+        super()._verify_hook(hook, hookmethod)
         if "__multicall__" in hookmethod.argnames:
             fslineno = _pytest._code.getfslineno(hookmethod.function)
             warning = dict(code="I1",
@@ -205,7 +205,7 @@ class PytestPluginManager(PluginManager):
             self._warn(warning)
 
     def register(self, plugin, name=None):
-        ret = super(PytestPluginManager, self).register(plugin, name)
+        ret = super().register(plugin, name)
         if ret:
             self.hook.pytest_plugin_registered.call_historic(
                       kwargs=dict(plugin=plugin, manager=self))
@@ -384,7 +384,7 @@ class PytestPluginManager(PluginManager):
         try:
             __import__(importspec)
         except ImportError as e:
-            new_exc = ImportError('Error importing plugin "%s": %s' % (modname, e))
+            new_exc = ImportError('Error importing plugin "{}": {}'.format(modname, e))
             # copy over name and path attributes
             for attr in ('name', 'path'):
                 if hasattr(e, attr):
@@ -531,7 +531,7 @@ class ArgumentError(Exception):
 
     def __str__(self):
         if self.option_id:
-            return "option %s: %s" % (self.option_id, self.msg)
+            return "option {}: {}".format(self.option_id, self.msg)
         else:
             return self.msg
 
@@ -722,7 +722,7 @@ class MyOptionParser(argparse.ArgumentParser):
                 if arg and arg[0] == '-':
                     lines = ['unrecognized arguments: %s' % (' '.join(argv))]
                     for k, v in sorted(self.extra_info.items()):
-                        lines.append('  %s: %s' % (k, v))
+                        lines.append('  {}: {}'.format(k, v))
                     self.error('\n'.join(lines))
             getattr(args, FILE_OR_DIR).extend(argv)
         return args
@@ -784,7 +784,7 @@ def _ensure_removed_sysmodule(modname):
     except KeyError:
         pass
 
-class CmdOptions(object):
+class CmdOptions:
     """ holds cmdline options as attributes."""
     def __init__(self, values=()):
         self.__dict__.update(values)
@@ -800,7 +800,7 @@ class Notset:
 notset = Notset()
 FILE_OR_DIR = 'file_or_dir'
 
-class Config(object):
+class Config:
     """ access to configuration values, pluginmanager and plugin hooks.  """
 
     def __init__(self, pluginmanager):
@@ -809,7 +809,7 @@ class Config(object):
         self.option = CmdOptions()
         _a = FILE_OR_DIR
         self._parser = Parser(
-            usage="%%(prog)s [options] [%s] [%s] [...]" % (_a, _a),
+            usage="%(prog)s [options] [{}] [{}] [...]".format(_a, _a),
             processopt=self._processopt,
         )
         #: a pluginmanager instance
@@ -926,7 +926,7 @@ class Config(object):
         try:
             self.pluginmanager.load_setuptools_entrypoints("pytest11")
         except ImportError as e:
-            self.warn("I2", "could not load setuptools entry import: %s" % (e,))
+            self.warn("I2", "could not load setuptools entry import: {}".format(e))
         self.pluginmanager.consider_env()
         self.known_args_namespace = ns = self._parser.parse_known_args(args, namespace=self.option.copy())
         if self.known_args_namespace.confcutdir is None and self.inifile:
@@ -1016,7 +1016,7 @@ class Config(object):
         elif type == "args":
             return shlex.split(value)
         elif type == "linelist":
-            return [t for t in map(lambda x: x.strip(), value.split("\n")) if t]
+            return [t for t in [x.strip() for x in value.split("\n")] if t]
         elif type == "bool":
             return bool(_strtobool(value.strip()))
         else:
@@ -1058,7 +1058,7 @@ class Config(object):
             if skip:
                 import pytest
                 pytest.skip("no %r option found" %(name,))
-            raise ValueError("no option named %r" % (name,))
+            raise ValueError("no option named {!r}".format(name))
 
     def getvalue(self, name, path=None):
         """ (deprecated, use getoption()) """
@@ -1189,4 +1189,4 @@ def _strtobool(val):
     elif val in ('n', 'no', 'f', 'false', 'off', '0'):
         return 0
     else:
-        raise ValueError("invalid truth value %r" % (val,))
+        raise ValueError("invalid truth value {!r}".format(val))
diff --git a/python/pytest/_pytest/doctest.py b/python/pytest/_pytest/doctest.py
index a57f7a4949..368487db28 100644
--- a/python/pytest/_pytest/doctest.py
+++ b/python/pytest/_pytest/doctest.py
@@ -1,5 +1,4 @@
 """ discover and run doctests in modules and test files."""
-from __future__ import absolute_import
 
 import traceback
 
@@ -61,7 +60,7 @@ class ReprFailDoctest(TerminalRepr):
 class DoctestItem(pytest.Item):
 
     def __init__(self, name, parent, runner=None, dtest=None):
-        super(DoctestItem, self).__init__(name, parent)
+        super().__init__(name, parent)
         self.runner = runner
         self.dtest = dtest
         self.obj = None
@@ -78,7 +77,7 @@ class DoctestItem(pytest.Item):
         self.runner.run(self.dtest)
 
     def repr_failure(self, excinfo):
-        import doctest
+        from . import doctest
         if excinfo.errisinstance((doctest.DocTestFailure,
                                   doctest.UnexpectedException)):
             doctestfailure = excinfo.value
@@ -104,7 +103,7 @@ class DoctestItem(pytest.Item):
                 lines = ['EXAMPLE LOCATION UNKNOWN, not showing all tests of that example']
                 indent = '>>>'
                 for line in example.source.splitlines():
-                    lines.append('??? %s %s' % (indent, line))
+                    lines.append('??? {} {}'.format(indent, line))
                     indent = '...'
             if excinfo.errisinstance(doctest.DocTestFailure):
                 lines += checker.output_difference(example,
@@ -116,14 +115,14 @@ class DoctestItem(pytest.Item):
                 lines += traceback.format_exception(*excinfo.value.exc_info)
             return ReprFailDoctest(reprlocation, lines)
         else:
-            return super(DoctestItem, self).repr_failure(excinfo)
+            return super().repr_failure(excinfo)
 
     def reportinfo(self):
         return self.fspath, None, "[doctest] %s" % self.name
 
 
 def _get_flag_lookup():
-    import doctest
+    from . import doctest
     return dict(DONT_ACCEPT_TRUE_FOR_1=doctest.DONT_ACCEPT_TRUE_FOR_1,
                 DONT_ACCEPT_BLANKLINE=doctest.DONT_ACCEPT_BLANKLINE,
                 NORMALIZE_WHITESPACE=doctest.NORMALIZE_WHITESPACE,
@@ -147,7 +146,7 @@ def get_optionflags(parent):
 class DoctestTextfile(DoctestItem, pytest.Module):
 
     def runtest(self):
-        import doctest
+        from . import doctest
         fixture_request = _setup_fixtures(self)
 
         # inspired by doctest.testfile; ideally we would use it directly,
@@ -173,7 +172,7 @@ def _check_all_skipped(test):
     """raises pytest.skip() if all examples in the given DocTest have the SKIP
     option set.
     """
-    import doctest
+    from . import doctest
     all_skipped = all(x.options.get(doctest.SKIP, False) for x in test.examples)
     if all_skipped:
         pytest.skip('all tests skipped by +SKIP option')
@@ -181,7 +180,7 @@ def _check_all_skipped(test):
 
 class DoctestModule(pytest.Module):
     def collect(self):
-        import doctest
+        from . import doctest
         if self.fspath.basename == "conftest.py":
             module = self.config.pluginmanager._importconftest(self.fspath)
         else:
@@ -231,7 +230,7 @@ def _get_checker():
     if hasattr(_get_checker, 'LiteralsOutputChecker'):
         return _get_checker.LiteralsOutputChecker()
 
-    import doctest
+    from . import doctest
     import re
 
     class LiteralsOutputChecker(doctest.OutputChecker):
@@ -278,7 +277,7 @@ def _get_allow_unicode_flag():
     """
     Registers and returns the ALLOW_UNICODE flag.
     """
-    import doctest
+    from . import doctest
     return doctest.register_optionflag('ALLOW_UNICODE')
 
 
@@ -286,5 +285,5 @@ def _get_allow_bytes_flag():
     """
     Registers and returns the ALLOW_BYTES flag.
     """
-    import doctest
+    from . import doctest
     return doctest.register_optionflag('ALLOW_BYTES')
diff --git a/python/pytest/_pytest/helpconfig.py b/python/pytest/_pytest/helpconfig.py
index 1df0c56ac7..ac6e9f0a5c 100644
--- a/python/pytest/_pytest/helpconfig.py
+++ b/python/pytest/_pytest/helpconfig.py
@@ -76,7 +76,7 @@ def showhelp(config):
         help, type, default = config._parser._inidict[name]
         if type is None:
             type = "string"
-        spec = "%s (%s)" % (name, type)
+        spec = "{} ({})".format(name, type)
         line = "  %-24s %s" %(spec, help)
         tw.line(line[:tw.fullwidth])
 
@@ -113,7 +113,7 @@ def getpluginversioninfo(config):
         lines.append("setuptools registered plugins:")
         for plugin, dist in plugininfo:
             loc = getattr(plugin, '__file__', repr(plugin))
-            content = "%s-%s at %s" % (dist.project_name, dist.version, loc)
+            content = "{}-{} at {}".format(dist.project_name, dist.version, loc)
             lines.append("  " + content)
     return lines
 
diff --git a/python/pytest/_pytest/junitxml.py b/python/pytest/_pytest/junitxml.py
index f4de1343ed..aa54a608e0 100644
--- a/python/pytest/_pytest/junitxml.py
+++ b/python/pytest/_pytest/junitxml.py
@@ -14,14 +14,12 @@ import re
 import sys
 import time
 import pytest
+unichr = chr
 
 # Python 2.X and 3.X compatibility
-if sys.version_info[0] < 3:
-    from codecs import open
-else:
-    unichr = chr
-    unicode = str
-    long = int
+unichr = chr
+str = str
+long = int
 
 
 class Junit(py.xml.Namespace):
@@ -37,11 +35,11 @@ _legal_ranges = (
     (0x20, 0x7E), (0x80, 0xD7FF), (0xE000, 0xFFFD), (0x10000, 0x10FFFF),
 )
 _legal_xml_re = [
-    unicode("%s-%s") % (unichr(low), unichr(high))
+    str("%s-%s") % (unichr(low), unichr(high))
     for (low, high) in _legal_ranges if low < sys.maxunicode
 ]
 _legal_xml_re = [unichr(x) for x in _legal_chars] + _legal_xml_re
-illegal_xml_re = re.compile(unicode('[^%s]') % unicode('').join(_legal_xml_re))
+illegal_xml_re = re.compile(str('[^%s]') % str('').join(_legal_xml_re))
 del _legal_chars
 del _legal_ranges
 del _legal_xml_re
@@ -53,14 +51,14 @@ def bin_xml_escape(arg):
     def repl(matchobj):
         i = ord(matchobj.group())
         if i <= 0xFF:
-            return unicode('#x%02X') % i
+            return str('#x%02X') % i
         else:
-            return unicode('#x%04X') % i
+            return str('#x%04X') % i
 
     return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg)))
 
 
-class _NodeReporter(object):
+class _NodeReporter:
     def __init__(self, nodeid, xml):
 
         self.id = nodeid
@@ -139,7 +137,7 @@ class _NodeReporter(object):
         else:
             if hasattr(report.longrepr, "reprcrash"):
                 message = report.longrepr.reprcrash.message
-            elif isinstance(report.longrepr, (unicode, str)):
+            elif isinstance(report.longrepr, (str, str)):
                 message = report.longrepr
             else:
                 message = str(report.longrepr)
@@ -173,13 +171,13 @@ class _NodeReporter(object):
             if skipreason.startswith("Skipped: "):
                 skipreason = bin_xml_escape(skipreason[9:])
             self.append(
-                Junit.skipped("%s:%s: %s" % (filename, lineno, skipreason),
+                Junit.skipped("{}:{}: {}".format(filename, lineno, skipreason),
                               type="pytest.skip",
                               message=skipreason))
         self._write_captured_output(report)
 
     def finalize(self):
-        data = self.to_xml().unicode(indent=0)
+        data = self.to_xml().str(indent=0)
         self.__dict__.clear()
         self.to_xml = lambda: py.xml.raw(data)
 
@@ -252,7 +250,7 @@ def mangle_test_address(address):
     return names
 
 
-class LogXML(object):
+class LogXML:
     def __init__(self, logfile, prefix):
         logfile = os.path.expanduser(os.path.expandvars(logfile))
         self.logfile = os.path.normpath(os.path.abspath(logfile))
@@ -379,7 +377,7 @@ class LogXML(object):
             failures=self.stats['failure'],
             skips=self.stats['skipped'],
             tests=numtests,
-            time="%.3f" % suite_time_delta, ).unicode(indent=0))
+            time="%.3f" % suite_time_delta, ).str(indent=0))
         logfile.close()
 
     def pytest_terminal_summary(self, terminalreporter):
diff --git a/python/pytest/_pytest/main.py b/python/pytest/_pytest/main.py
index 8654d7af62..5d9598bb66 100644
--- a/python/pytest/_pytest/main.py
+++ b/python/pytest/_pytest/main.py
@@ -9,7 +9,7 @@ import _pytest._code
 import py
 import pytest
 try:
-    from collections import MutableMapping as MappingMixin
+    from collections.abc import MutableMapping as MappingMixin
 except ImportError:
     from UserDict import DictMixin as MappingMixin
 
@@ -25,7 +25,7 @@ EXIT_INTERNALERROR = 3
 EXIT_USAGEERROR = 4
 EXIT_NOTESTSCOLLECTED = 5
 
-name_re = re.compile("^[a-zA-Z_]\w*$")
+name_re = re.compile(r"^[a-zA-Z_]\w*$")
 
 def pytest_addoption(parser):
     parser.addini("norecursedirs", "directory patterns to avoid for recursion",
@@ -212,10 +212,10 @@ class NodeKeywords(MappingMixin):
         return list(self)
 
     def __repr__(self):
-        return "" % (self.node, )
+        return "".format(self.node)
 
 
-class Node(object):
+class Node:
     """ base class for Collector and Item the test collection tree.
     Collector subclasses have children, Items are terminal nodes."""
 
@@ -451,7 +451,7 @@ class FSCollector(Collector):
             if rel:
                 name = rel
             name = name.replace(os.sep, "/")
-        super(FSCollector, self).__init__(name, parent, config, session)
+        super().__init__(name, parent, config, session)
         self.fspath = fspath
 
     def _makeid(self):
@@ -470,7 +470,7 @@ class Item(Node):
     nextitem = None
 
     def __init__(self, name, parent=None, config=None, session=None):
-        super(Item, self).__init__(name, parent, config, session)
+        super().__init__(name, parent, config, session)
         self._report_sections = []
 
     def add_report_section(self, when, key, content):
@@ -589,8 +589,8 @@ class Session(FSCollector):
         if self._notfound:
             errors = []
             for arg, exc in self._notfound:
-                line = "(no name %r in any of %r)" % (arg, exc.args[0])
-                errors.append("not found: %s\n%s" % (arg, line))
+                line = "(no name {!r} in any of {!r})".format(arg, exc.args[0])
+                errors.append("not found: {}\n{}".format(arg, line))
                 #XXX: test this
             raise pytest.UsageError(*errors)
         if not genitems:
@@ -607,8 +607,7 @@ class Session(FSCollector):
             self.trace("processing argument", arg)
             self.trace.root.indent += 1
             try:
-                for x in self._collect(arg):
-                    yield x
+                yield from self._collect(arg)
             except NoMatch:
                 # we are inside a make_report hook so
                 # we cannot directly pass through the exception
@@ -739,6 +738,5 @@ class Session(FSCollector):
             rep = collect_one_node(node)
             if rep.passed:
                 for subnode in rep.result:
-                    for x in self.genitems(subnode):
-                        yield x
+                    yield from self.genitems(subnode)
             node.ihook.pytest_collectreport(report=rep)
diff --git a/python/pytest/_pytest/mark.py b/python/pytest/_pytest/mark.py
index d8b60def36..e30169292f 100644
--- a/python/pytest/_pytest/mark.py
+++ b/python/pytest/_pytest/mark.py
@@ -196,7 +196,7 @@ class MarkGenerator:
             x = beginning[0].split("(", 1)[0]
             l.add(x)
         if name not in self._markers:
-            raise AttributeError("%r not a registered marker" % (name,))
+            raise AttributeError("{!r} not a registered marker".format(name))
 
 def istestfunc(func):
     return hasattr(func, "__call__") and \
@@ -247,7 +247,7 @@ class MarkDecorator:
     def __repr__(self):
         d = self.__dict__.copy()
         name = d.pop('name')
-        return "" % (name, d)
+        return "".format(name, d)
 
     def __call__(self, *args, **kwargs):
         """ if passed a single callable argument: decorate it with mark info.
@@ -295,7 +295,7 @@ class MarkInfo:
         self._arglist = [(args, kwargs.copy())]
 
     def __repr__(self):
-        return "" % (
+        return "".format(
             self.name, self.args, self.kwargs
         )
 
diff --git a/python/pytest/_pytest/monkeypatch.py b/python/pytest/_pytest/monkeypatch.py
index d4c169d37a..bbb46c00af 100644
--- a/python/pytest/_pytest/monkeypatch.py
+++ b/python/pytest/_pytest/monkeypatch.py
@@ -56,7 +56,7 @@ def resolve(name):
                 raise
             else:
                 raise ImportError(
-                    'import error in %s: %s' % (used, ex)
+                    'import error in {}: {}'.format(used, ex)
                 )
         found = annotated_getattr(found, part, used)
     return found
@@ -67,7 +67,7 @@ def annotated_getattr(obj, name, ann):
         obj = getattr(obj, name)
     except AttributeError:
         raise AttributeError(
-                '%r object at %s has no attribute %r' % (
+                '{!r} object at {} has no attribute {!r}'.format(
                     type(obj).__name__, ann, name
                 )
         )
@@ -129,7 +129,7 @@ class monkeypatch:
 
         oldval = getattr(target, name, notset)
         if raising and oldval is notset:
-            raise AttributeError("%r has no attribute %r" % (target, name))
+            raise AttributeError("{!r} has no attribute {!r}".format(target, name))
 
         # avoid class descriptors like staticmethod/classmethod
         if inspect.isclass(target):
diff --git a/python/pytest/_pytest/pastebin.py b/python/pytest/_pytest/pastebin.py
index 4ec62d0228..8e103db57e 100644
--- a/python/pytest/_pytest/pastebin.py
+++ b/python/pytest/_pytest/pastebin.py
@@ -53,11 +53,8 @@ def create_new_paste(contents):
     :returns: url to the pasted contents
     """
     import re
-    if sys.version_info < (3, 0):
-        from urllib import urlopen, urlencode
-    else:
-        from urllib.request import urlopen
-        from urllib.parse import urlencode
+    from urllib.request import urlopen
+    from urllib.parse import urlencode
 
     params = {
         'code': contents,
@@ -68,7 +65,7 @@ def create_new_paste(contents):
     response = urlopen(url, data=urlencode(params).encode('ascii')).read()
     m = re.search(r'href="/raw/(\w+)"', response.decode('utf-8'))
     if m:
-        return '%s/show/%s' % (url, m.group(1))
+        return '{}/show/{}'.format(url, m.group(1))
     else:
         return 'bad response: ' + response
 
diff --git a/python/pytest/_pytest/pdb.py b/python/pytest/_pytest/pdb.py
index 84c920d172..256863f0cb 100644
--- a/python/pytest/_pytest/pdb.py
+++ b/python/pytest/_pytest/pdb.py
@@ -1,6 +1,5 @@
 """ interactive debugging with PDB, the Python Debugger. """
-from __future__ import absolute_import
-import pdb
+from . import pdb
 import sys
 
 import pytest
@@ -83,7 +82,7 @@ def _enter_pdb(node, excinfo, rep):
 def _postmortem_traceback(excinfo):
     # A doctest.UnexpectedException is not useful for post_mortem.
     # Use the underlying exception instead:
-    from doctest import UnexpectedException
+    from .doctest import UnexpectedException
     if isinstance(excinfo.value, UnexpectedException):
         return excinfo.value.exc_info[2]
     else:
diff --git a/python/pytest/_pytest/pytester.py b/python/pytest/_pytest/pytester.py
index faed7f581c..5966219e8f 100644
--- a/python/pytest/_pytest/pytester.py
+++ b/python/pytest/_pytest/pytester.py
@@ -1,4 +1,5 @@
 """ (disabled by default) support for testing pytest and pytest plugins. """
+from __future__ import print_function
 import codecs
 import gc
 import os
@@ -45,7 +46,7 @@ def pytest_configure(config):
             config.pluginmanager.register(checker)
 
 
-class LsofFdLeakChecker(object):
+class LsofFdLeakChecker:
     def get_open_files(self):
         out = self._exec_lsof()
         open_files = self._parse_lsof_output(out)
@@ -91,7 +92,7 @@ class LsofFdLeakChecker(object):
             gc.collect()
         lines2 = self.get_open_files()
 
-        new_fds = set([t[0] for t in lines2]) - set([t[0] for t in lines1])
+        new_fds = {t[0] for t in lines2} - {t[0] for t in lines1}
         leaked_files = [t for t in lines2 if t[0] in new_fds]
         if leaked_files:
             error = []
@@ -147,7 +148,7 @@ def anypython(request):
                 executable = py.path.local(executable)
                 if executable.check():
                     return executable
-        pytest.skip("no suitable %s found" % (name,))
+        pytest.skip("no suitable {} found".format(name))
     return executable
 
 # used at least by pytest-xdist plugin
@@ -232,7 +233,7 @@ class HookRecorder:
                     break
                 print_("NONAMEMATCH", name, "with", call)
             else:
-                pytest.fail("could not find %r check %r" % (name, check))
+                pytest.fail("could not find {!r} check {!r}".format(name, check))
 
     def popcall(self, name):
         __tracebackhide__ = True
@@ -240,7 +241,7 @@ class HookRecorder:
             if call._name == name:
                 del self.calls[i]
                 return call
-        lines = ["could not find call %r, in:" % (name,)]
+        lines = ["could not find call {!r}, in:".format(name)]
         lines.extend(["  %s" % str(x) for x in self.calls])
         pytest.fail("\n".join(lines))
 
@@ -327,7 +328,7 @@ def testdir(request, tmpdir_factory):
     return Testdir(request, tmpdir_factory)
 
 
-rex_outcome = re.compile("(\d+) ([\w-]+)")
+rex_outcome = re.compile(r"(\d+) ([\w-]+)")
 class RunResult:
     """The result of running a command.
 
@@ -418,7 +419,7 @@ class Testdir:
             self._runpytest_method = self.runpytest_subprocess
 
     def __repr__(self):
-        return "" % (self.tmpdir,)
+        return "".format(self.tmpdir)
 
     def finalize(self):
         """Clean up global state artifacts.
@@ -870,8 +871,8 @@ class Testdir:
 
         """
         env = os.environ.copy()
-        env['PYTHONPATH'] = os.pathsep.join(filter(None, [
-            str(os.getcwd()), env.get('PYTHONPATH', '')]))
+        env['PYTHONPATH'] = os.pathsep.join([_f for _f in [
+            str(os.getcwd()), env.get('PYTHONPATH', '')] if _f])
         kw['env'] = env
         return subprocess.Popen(cmdargs,
                                 stdout=stdout, stderr=stderr, **kw)
@@ -920,7 +921,7 @@ class Testdir:
             for line in lines:
                 py.builtin.print_(line, file=fp)
         except UnicodeEncodeError:
-            print("couldn't print to %s because of encoding" % (fp,))
+            print(("couldn't print to {} because of encoding".format(fp)))
 
     def _getpytestargs(self):
         # we cannot use "(sys.executable,script)"
@@ -977,7 +978,7 @@ class Testdir:
         """
         basetemp = self.tmpdir.mkdir("pexpect")
         invoke = " ".join(map(str, self._getpytestargs()))
-        cmd = "%s --basetemp=%s %s" % (invoke, basetemp, string)
+        cmd = "{} --basetemp={} {}".format(invoke, basetemp, string)
         return self.spawn(cmd, expect_timeout=expect_timeout)
 
     def spawn(self, cmd, expect_timeout=10.0):
@@ -1002,8 +1003,8 @@ def getdecoded(out):
         try:
             return out.decode("utf-8")
         except UnicodeDecodeError:
-            return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % (
-                    py.io.saferepr(out),)
+            return "INTERNAL not-utf8-decodeable, truncated string:\n{}".format(
+                    py.io.saferepr(out))
 
 
 class LineComp:
@@ -1107,4 +1108,4 @@ class LineMatcher:
                     show("    and:", repr(nextline))
                 extralines.append(nextline)
             else:
-                pytest.fail("remains unmatched: %r, see stderr" % (line,))
+                pytest.fail("remains unmatched: {!r}, see stderr".format(line))
diff --git a/python/pytest/_pytest/python.py b/python/pytest/_pytest/python.py
index 21d78aea33..e22dc44a93 100644
--- a/python/pytest/_pytest/python.py
+++ b/python/pytest/_pytest/python.py
@@ -52,7 +52,7 @@ if  sys.version_info[:2] == (2, 6):
         something on __getattr__ calls (see #1035).
         Backport of https://hg.python.org/cpython/rev/35bf8f7a8edc
         """
-        return isinstance(object, (type, types.ClassType))
+        return isinstance(object, (type, type))
 
 def _has_positional_arg(func):
     return func.__code__.co_argcount
@@ -96,7 +96,7 @@ def getimfunc(func):
         return func.__func__
     except AttributeError:
         try:
-            return func.im_func
+            return func.__func__
         except AttributeError:
             return func
 
@@ -188,8 +188,8 @@ def pyobj_property(name):
         node = self.getparent(getattr(pytest, name))
         if node is not None:
             return node.obj
-    doc = "python %s object this node was collected from (can be None)." % (
-          name.lower(),)
+    doc = "python {} object this node was collected from (can be None).".format(
+          name.lower())
     return property(get, None, None, doc)
 
 
@@ -337,7 +337,7 @@ def is_generator(func):
         # assume them to not be generators
         return False
 
-class PyobjContext(object):
+class PyobjContext:
     module = pyobj_property("Module")
     cls = pyobj_property("Class")
     instance = pyobj_property("Instance")
@@ -602,7 +602,7 @@ class Module(pytest.File, PyCollector):
 
     def collect(self):
         self.session._fixturemanager.parsefactories(self)
-        return super(Module, self).collect()
+        return super().collect()
 
     def _importtestmodule(self):
         # we assume we are only called once per module
@@ -683,7 +683,7 @@ class Instance(PyCollector):
 
     def collect(self):
         self.session._fixturemanager.parsefactories(self)
-        return super(Instance, self).collect()
+        return super().collect()
 
     def newinstance(self):
         self.obj = self._getobj()
@@ -741,7 +741,7 @@ class FunctionMixin(PyobjMixin):
         if excinfo.errisinstance(pytest.fail.Exception):
             if not excinfo.value.pytrace:
                 return py._builtin._totext(excinfo.value)
-        return super(FunctionMixin, self)._repr_failure_py(excinfo,
+        return super()._repr_failure_py(excinfo,
             style=style)
 
     def repr_failure(self, excinfo, outerr=None):
@@ -821,7 +821,7 @@ def fillfixtures(function):
 
 _notexists = object()
 
-class CallSpec2(object):
+class CallSpec2:
     def __init__(self, metafunc):
         self.metafunc = metafunc
         self.funcargs = {}
@@ -861,7 +861,7 @@ class CallSpec2(object):
 
     @property
     def id(self):
-        return "-".join(map(str, filter(None, self._idlist)))
+        return "-".join(map(str, [_f for _f in self._idlist if _f]))
 
     def setmulti(self, valtypes, argnames, valset, id, keywords, scopenum,
                  param_index):
@@ -1127,7 +1127,7 @@ def _idval(val, argname, idx, idfn):
         return str(val)
     elif isclass(val) and hasattr(val, '__name__'):
         return val.__name__
-    elif _PY2 and isinstance(val, unicode):
+    elif _PY2 and isinstance(val, str):
         # special case for python 2: if a unicode string is
         # convertible to ascii, return it as an str() object instead
         try:
@@ -1318,9 +1318,9 @@ def raises(expected_exception, *args, **kwargs):
             func(*args[1:], **kwargs)
         except expected_exception:
             return _pytest._code.ExceptionInfo()
-    pytest.fail("DID NOT RAISE {0}".format(expected_exception))
+    pytest.fail("DID NOT RAISE {}".format(expected_exception))
 
-class RaisesContext(object):
+class RaisesContext:
     def __init__(self, expected_exception):
         self.expected_exception = expected_exception
         self.excinfo = None
@@ -1355,7 +1355,7 @@ class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
     def __init__(self, name, parent, args=None, config=None,
                  callspec=None, callobj=NOTSET, keywords=None, session=None,
                  fixtureinfo=None):
-        super(Function, self).__init__(name, parent, config=config,
+        super().__init__(name, parent, config=config,
                                        session=session)
         self._args = args
         if callobj is not NOTSET:
@@ -1415,7 +1415,7 @@ class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
         self.ihook.pytest_pyfunc_call(pyfuncitem=self)
 
     def setup(self):
-        super(Function, self).setup()
+        super().setup()
         fillfixtures(self)
 
 
@@ -1431,7 +1431,7 @@ def scopeproperty(name=None, doc=None):
         def provide(self):
             if func.__name__ in scope2props[self.scope]:
                 return func(self)
-            raise AttributeError("%s not available in %s-scoped context" % (
+            raise AttributeError("{} not available in {}-scoped context".format(
                 scopename, self.scope))
         return property(provide, None, None, func.__doc__)
     return decoratescope
@@ -1736,7 +1736,7 @@ class SubRequest(FixtureRequest):
         self._fixturemanager = request._fixturemanager
 
     def __repr__(self):
-        return "" % (self.fixturename, self._pyfuncitem)
+        return "".format(self.fixturename, self._pyfuncitem)
 
 
 class ScopeMismatchError(Exception):
@@ -1762,7 +1762,7 @@ class FixtureLookupError(LookupError):
         tblines = []
         addline = tblines.append
         stack = [self.request._pyfuncitem.obj]
-        stack.extend(map(lambda x: x.func, self.fixturestack))
+        stack.extend([x.func for x in self.fixturestack])
         msg = self.msg
         if msg is not None:
             # the last fixture raise an error, let's present
@@ -1772,11 +1772,11 @@ class FixtureLookupError(LookupError):
             fspath, lineno = getfslineno(function)
             try:
                 lines, _ = inspect.getsourcelines(get_real_func(function))
-            except (IOError, IndexError):
+            except (OSError, IndexError):
                 error_msg = "file %s, line %s: source code not available"
                 addline(error_msg % (fspath, lineno+1))
             else:
-                addline("file %s, line %s" % (fspath, lineno+1))
+                addline("file {}, line {}".format(fspath, lineno+1))
                 for i, line in enumerate(lines):
                     line = line.rstrip()
                     addline("  " + line)
@@ -1791,7 +1791,7 @@ class FixtureLookupError(LookupError):
                 faclist = list(fm._matchfactories(fixturedef, parentid))
                 if faclist:
                     available.append(name)
-            msg = "fixture %r not found" % (self.argname,)
+            msg = "fixture {!r} not found".format(self.argname)
             msg += "\n available fixtures: %s" %(", ".join(available),)
             msg += "\n use 'py.test --fixtures [testpath]' for help on them."
 
@@ -2023,7 +2023,7 @@ class FixtureManager:
 
 def fail_fixturefunc(fixturefunc, msg):
     fs, lineno = getfslineno(fixturefunc)
-    location = "%s:%s" % (fs, lineno+1)
+    location = "{}:{}".format(fs, lineno+1)
     source = _pytest._code.Source(fixturefunc)
     pytest.fail(msg + ":\n\n" + str(source.indent()) + "\n" + location,
                 pytrace=False)
diff --git a/python/pytest/_pytest/recwarn.py b/python/pytest/_pytest/recwarn.py
index a89474c036..6cecb5e8ee 100644
--- a/python/pytest/_pytest/recwarn.py
+++ b/python/pytest/_pytest/recwarn.py
@@ -71,7 +71,7 @@ def deprecated_call(func=None, *args, **kwargs):
     deprecation_categories = (DeprecationWarning, PendingDeprecationWarning)
     if not any(issubclass(c, deprecation_categories) for c in categories):
         __tracebackhide__ = True
-        raise AssertionError("%r did not produce DeprecationWarning" % (func,))
+        raise AssertionError("{!r} did not produce DeprecationWarning".format(func))
     return ret
 
 
@@ -110,7 +110,7 @@ def warns(expected_warning, *args, **kwargs):
             return func(*args[1:], **kwargs)
 
 
-class RecordedWarning(object):
+class RecordedWarning:
     def __init__(self, message, category, filename, lineno, file, line):
         self.message = message
         self.category = category
@@ -120,7 +120,7 @@ class RecordedWarning(object):
         self.line = line
 
 
-class WarningsRecorder(object):
+class WarningsRecorder:
     """A context manager to record raised warnings.
 
     Adapted from `warnings.catch_warnings`.
@@ -195,7 +195,7 @@ class WarningsRecorder(object):
 
 class WarningsChecker(WarningsRecorder):
     def __init__(self, expected_warning=None, module=None):
-        super(WarningsChecker, self).__init__(module=module)
+        super().__init__(module=module)
 
         msg = ("exceptions must be old-style classes or "
                "derived from Warning, not %s")
@@ -211,7 +211,7 @@ class WarningsChecker(WarningsRecorder):
         self.expected_warning = expected_warning
 
     def __exit__(self, *exc_info):
-        super(WarningsChecker, self).__exit__(*exc_info)
+        super().__exit__(*exc_info)
 
         # only check if we're not currently handling an exception
         if all(a is None for a in exc_info):
diff --git a/python/pytest/_pytest/resultlog.py b/python/pytest/_pytest/resultlog.py
index 3670f0214c..1d963adba8 100644
--- a/python/pytest/_pytest/resultlog.py
+++ b/python/pytest/_pytest/resultlog.py
@@ -52,13 +52,13 @@ def generic_path(item):
         fspath = newfspath
     return ''.join(gpath)
 
-class ResultLog(object):
+class ResultLog:
     def __init__(self, config, logfile):
         self.config = config
         self.logfile = logfile # preferably line buffered
 
     def write_log_entry(self, testpath, lettercode, longrepr):
-        py.builtin.print_("%s %s" % (lettercode, testpath), file=self.logfile)
+        py.builtin.print_("{} {}".format(lettercode, testpath), file=self.logfile)
         for line in longrepr.splitlines():
             py.builtin.print_(" %s" % line, file=self.logfile)
 
diff --git a/python/pytest/_pytest/runner.py b/python/pytest/_pytest/runner.py
index cde94c8c89..d35b3f3232 100644
--- a/python/pytest/_pytest/runner.py
+++ b/python/pytest/_pytest/runner.py
@@ -159,8 +159,8 @@ class CallInfo:
         if self.excinfo:
             status = "exception: %s" % str(self.excinfo.value)
         else:
-            status = "result: %r" % (self.result,)
-        return "" % (self.when, status)
+            status = "result: {!r}".format(self.result)
+        return "".format(self.when, status)
 
 def getslaveinfoline(node):
     try:
@@ -168,11 +168,11 @@ def getslaveinfoline(node):
     except AttributeError:
         d = node.slaveinfo
         ver = "%s.%s.%s" % d['version_info'][:3]
-        node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
+        node._slaveinfocache = s = "[{}] {} -- Python {} {}".format(
             d['id'], d['sysplatform'], ver, d['executable'])
         return s
 
-class BaseReport(object):
+class BaseReport:
 
     def __init__(self, **kw):
         self.__dict__.update(kw)
@@ -209,7 +209,7 @@ class BaseReport(object):
 def pytest_runtest_makereport(item, call):
     when = call.when
     duration = call.stop-call.start
-    keywords = dict([(x,1) for x in item.keywords])
+    keywords = {x:1 for x in item.keywords}
     excinfo = call.excinfo
     sections = []
     if not call.excinfo:
@@ -273,7 +273,7 @@ class TestReport(BaseReport):
         self.__dict__.update(extra)
 
     def __repr__(self):
-        return "" % (
+        return "".format(
             self.nodeid, self.when, self.outcome)
 
 class TeardownErrorReport(BaseReport):
@@ -323,7 +323,7 @@ class CollectReport(BaseReport):
         return (self.fspath, None, self.fspath)
 
     def __repr__(self):
-        return "" % (
+        return "".format(
                 self.nodeid, len(self.result), self.outcome)
 
 class CollectErrorRepr(TerminalRepr):
@@ -332,7 +332,7 @@ class CollectErrorRepr(TerminalRepr):
     def toterminal(self, out):
         out.line(self.longrepr, red=True)
 
-class SetupState(object):
+class SetupState:
     """ shared state for setting up/tearing down test items or collectors. """
     def __init__(self):
         self.stack = []
diff --git a/python/pytest/_pytest/skipping.py b/python/pytest/_pytest/skipping.py
index 18e038d2c8..0ef3cad1b1 100644
--- a/python/pytest/_pytest/skipping.py
+++ b/python/pytest/_pytest/skipping.py
@@ -112,7 +112,7 @@ class MarkEvaluator:
         try:
             d.update(func.__globals__)
         except AttributeError:
-            d.update(func.func_globals)
+            d.update(func.__globals__)
         return d
 
     def _istrue(self):
@@ -307,7 +307,7 @@ def show_xfailed(terminalreporter, lines):
         for rep in xfailed:
             pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
             reason = rep.wasxfail
-            lines.append("XFAIL %s" % (pos,))
+            lines.append("XFAIL {}".format(pos))
             if reason:
                 lines.append("  " + str(reason))
 
diff --git a/python/pytest/_pytest/standalonetemplate.py b/python/pytest/_pytest/standalonetemplate.py
index 484d5d1b25..13e4fcca1d 100755
--- a/python/pytest/_pytest/standalonetemplate.py
+++ b/python/pytest/_pytest/standalonetemplate.py
@@ -26,7 +26,7 @@ import sys
 import base64
 import zlib
 
-class DictImporter(object):
+class DictImporter:
     def __init__(self, sources):
         self.sources = sources
 
@@ -53,7 +53,7 @@ class DictImporter(object):
 
         co = compile(s, fullname, 'exec')
         module = sys.modules.setdefault(fullname, ModuleType(fullname))
-        module.__file__ = "%s/%s" % (__file__, fullname)
+        module.__file__ = "{}/{}".format(__file__, fullname)
         module.__loader__ = self
         if is_pkg:
             module.__path__ = [fullname]
@@ -73,15 +73,10 @@ if __name__ == "__main__":
     except ImportError:
         sys.stderr.write("ERROR: setuptools not installed\n")
         sys.exit(2)
-    if sys.version_info >= (3, 0):
-        exec("def do_exec(co, loc): exec(co, loc)\n")
-        import pickle
-        sources = sources.encode("ascii") # ensure bytes
-        sources = pickle.loads(zlib.decompress(base64.decodebytes(sources)))
-    else:
-        import cPickle as pickle
-        exec("def do_exec(co, loc): exec co in loc\n")
-        sources = pickle.loads(zlib.decompress(base64.decodestring(sources)))
+    exec("def do_exec(co, loc): exec(co, loc)\n")
+    import pickle
+    sources = sources.encode("ascii") # ensure bytes
+    sources = pickle.loads(zlib.decompress(base64.decodebytes(sources)))
 
     importer = DictImporter(sources)
     sys.meta_path.insert(0, importer)
diff --git a/python/pytest/_pytest/terminal.py b/python/pytest/_pytest/terminal.py
index 825f553ef2..113d6dd6b8 100644
--- a/python/pytest/_pytest/terminal.py
+++ b/python/pytest/_pytest/terminal.py
@@ -179,7 +179,7 @@ class TerminalReporter:
 
     def pytest_plugin_registered(self, plugin):
         if self.config.option.traceconfig:
-            msg = "PLUGIN registered: %s" % (plugin,)
+            msg = "PLUGIN registered: {}".format(plugin)
             # XXX this event may happen during setup/teardown time
             #     which unfortunately captures our output here
             #     which garbles our output if we use self.write_line
@@ -281,11 +281,11 @@ class TerminalReporter:
             return
         self.write_sep("=", "test session starts", bold=True)
         verinfo = platform.python_version()
-        msg = "platform %s -- Python %s" % (sys.platform, verinfo)
+        msg = "platform {} -- Python {}".format(sys.platform, verinfo)
         if hasattr(sys, 'pypy_version_info'):
             verinfo = ".".join(map(str, sys.pypy_version_info[:3]))
-            msg += "[pypy-%s-%s]" % (verinfo, sys.pypy_version_info[3])
-        msg += ", pytest-%s, py-%s, pluggy-%s" % (
+            msg += "[pypy-{}-{}]".format(verinfo, sys.pypy_version_info[3])
+        msg += ", pytest-{}, py-{}, pluggy-{}".format(
                pytest.__version__, py.__version__, pluggy.__version__)
         if self.verbosity > 0 or self.config.option.debug or \
            getattr(self.config.option, 'pastebin', None):
@@ -355,7 +355,7 @@ class TerminalReporter:
                 #if col.name == "()":
                 #    continue
                 indent = (len(stack) - 1) * "  "
-                self._tw.line("%s%s" % (indent, col))
+                self._tw.line("{}{}".format(indent, col))
 
     @pytest.hookimpl(hookwrapper=True)
     def pytest_sessionfinish(self, exitstatus):
@@ -447,7 +447,7 @@ class TerminalReporter:
                 return
             self.write_sep("=", "pytest-warning summary")
             for w in warnings:
-                self._tw.line("W%s %s %s" % (w.code,
+                self._tw.line("W{} {} {}".format(w.code,
                               w.fslocation, w.message))
 
     def summary_passes(self):
@@ -507,7 +507,7 @@ class TerminalReporter:
     def summary_stats(self):
         session_duration = time.time() - self._sessionstarttime
         (line, color) = build_summary_stats_line(self.stats)
-        msg = "%s in %.2f seconds" % (line, session_duration)
+        msg = "{} in {:.2f} seconds".format(line, session_duration)
         markup = {color: True, 'bold': True}
 
         if self.verbosity >= 0:
@@ -539,8 +539,7 @@ def repr_pythonversion(v=None):
 def flatten(l):
     for x in l:
         if isinstance(x, (list, tuple)):
-            for y in flatten(x):
-                yield y
+            yield from flatten(x)
         else:
             yield x
 
diff --git a/python/pytest/_pytest/tmpdir.py b/python/pytest/_pytest/tmpdir.py
index ebc48dbe5b..594cd8bbbb 100644
--- a/python/pytest/_pytest/tmpdir.py
+++ b/python/pytest/_pytest/tmpdir.py
@@ -115,7 +115,7 @@ def tmpdir(request, tmpdir_factory):
     path object.
     """
     name = request.node.name
-    name = re.sub("[\W]", "_", name)
+    name = re.sub(r"[\W]", "_", name)
     MAXVAL = 30
     if len(name) > MAXVAL:
         name = name[:MAXVAL]
diff --git a/python/pytest/_pytest/unittest.py b/python/pytest/_pytest/unittest.py
index 8120e94fbf..1880581e75 100644
--- a/python/pytest/_pytest/unittest.py
+++ b/python/pytest/_pytest/unittest.py
@@ -1,5 +1,4 @@
 """ discovery and running of std-library "unittest" style tests. """
-from __future__ import absolute_import
 
 import sys
 import traceback
@@ -37,10 +36,10 @@ class UnitTestCase(pytest.Class):
         teardown = getattr(cls, 'tearDownClass', None)
         if teardown is not None:
             self.addfinalizer(teardown)
-        super(UnitTestCase, self).setup()
+        super().setup()
 
     def collect(self):
-        from unittest import TestLoader
+        from .unittest import TestLoader
         cls = self.obj
         if not getattr(cls, "__test__", True):
             return
diff --git a/python/pytest/_pytest/vendored_packages/pluggy.py b/python/pytest/_pytest/vendored_packages/pluggy.py
index 2f848b23d3..659bad8ec9 100644
--- a/python/pytest/_pytest/vendored_packages/pluggy.py
+++ b/python/pytest/_pytest/vendored_packages/pluggy.py
@@ -186,11 +186,11 @@ class _TagTracer:
         indent = "  " * self.indent
 
         lines = [
-            "%s%s [%s]\n" % (indent, content, ":".join(tags))
+            "{}{} [{}]\n".format(indent, content, ":".join(tags))
         ]
 
         for name, value in extra.items():
-            lines.append("%s    %s: %s\n" % (indent, name, value))
+            lines.append("{}    {}: {}\n".format(indent, name, value))
         return lines
 
     def processmessage(self, tags, args):
@@ -281,7 +281,7 @@ class _CallOutcome:
 if not _py3:
     exec("""
 def _reraise(cls, val, tb):
-    raise cls, val, tb
+    raise cls(val, tb)
 """)
 
 
@@ -304,7 +304,7 @@ class _TracedHookExecution:
         self.pluginmanager._inner_hookexec = self.oldcall
 
 
-class PluginManager(object):
+class PluginManager:
     """ Core Pluginmanager class which manages registration
     of plugin objects and 1:N hook calling.
 
@@ -606,7 +606,7 @@ class _MultiCall:
         status = "%d meths" % (len(self.hook_impls),)
         if hasattr(self, "results"):
             status = ("%d results, " % len(self.results)) + status
-        return "<_MultiCall %s, kwargs=%r>" % (status, self.kwargs)
+        return "<_MultiCall {}, kwargs={!r}>".format(status, self.kwargs)
 
 
 def varnames(func, startindex=None):
@@ -662,7 +662,7 @@ class _HookRelay:
         self._trace = trace
 
 
-class _HookCaller(object):
+class _HookCaller:
     def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None):
         self.name = name
         self._wrappers = []
@@ -697,7 +697,7 @@ class _HookCaller(object):
                     return True
         if remove(self._wrappers) is None:
             if remove(self._nonwrappers) is None:
-                raise ValueError("plugin %r not found" % (plugin,))
+                raise ValueError("plugin {!r} not found".format(plugin))
 
     def _add_hookimpl(self, hookimpl):
         if hookimpl.hookwrapper:
@@ -717,7 +717,7 @@ class _HookCaller(object):
             methods.insert(i + 1, hookimpl)
 
     def __repr__(self):
-        return "<_HookCaller %r>" % (self.name,)
+        return "<_HookCaller {!r}>".format(self.name)
 
     def __call__(self, **kwargs):
         assert not self.is_historic()
@@ -765,13 +765,13 @@ class PluginValidationError(Exception):
 
 if hasattr(inspect, 'signature'):
     def _formatdef(func):
-        return "%s%s" % (
+        return "{}{}".format(
             func.__name__,
             str(inspect.signature(func))
         )
 else:
     def _formatdef(func):
-        return "%s%s" % (
+        return "{}{}".format(
             func.__name__,
             inspect.formatargspec(*inspect.getargspec(func))
         )
diff --git a/python/pytest/setup.py b/python/pytest/setup.py
index 7cdcdfb992..af5b95228d 100644
--- a/python/pytest/setup.py
+++ b/python/pytest/setup.py
@@ -99,7 +99,7 @@ def make_entry_points():
     points = cmdline_entrypoints(sys.version_info, sys.platform, basename)
     keys = list(points.keys())
     keys.sort()
-    l = ['%s = %s' % (x, points[x]) for x in keys]
+    l = ['{} = {}'.format(x, points[x]) for x in keys]
     return {'console_scripts': l}
 
 
diff --git a/python/pyyaml/examples/pygments-lexer/yaml.py b/python/pyyaml/examples/pygments-lexer/yaml.py
index 1ce9dac9e4..a2c91febda 100644
--- a/python/pyyaml/examples/pygments-lexer/yaml.py
+++ b/python/pyyaml/examples/pygments-lexer/yaml.py
@@ -1,4 +1,3 @@
-
 """
 yaml.py
 
@@ -22,7 +21,7 @@ class YAMLLexerContext(LexerContext):
     """Indentation context for the YAML lexer."""
 
     def __init__(self, *args, **kwds):
-        super(YAMLLexerContext, self).__init__(*args, **kwds)
+        super().__init__(*args, **kwds)
         self.indent_stack = []
         self.indent = -1
         self.next_indent = 0
@@ -426,6 +425,6 @@ class YAMLLexer(ExtendedRegexLexer):
     def get_tokens_unprocessed(self, text=None, context=None):
         if context is None:
             context = YAMLLexerContext(text, 0)
-        return super(YAMLLexer, self).get_tokens_unprocessed(text, context)
+        return super().get_tokens_unprocessed(text, context)
 
 
diff --git a/python/pyyaml/examples/yaml-highlight/yaml_hl.py b/python/pyyaml/examples/yaml-highlight/yaml_hl.py
index d6f7bf4eb2..8bc6520998 100755
--- a/python/pyyaml/examples/yaml-highlight/yaml_hl.py
+++ b/python/pyyaml/examples/yaml-highlight/yaml_hl.py
@@ -15,7 +15,7 @@ class Style:
                 continue
             for key in domain:
                 name = ''.join([part.capitalize() for part in key.split('-')])
-                cls = getattr(yaml, '%s%s' % (name, Class))
+                cls = getattr(yaml, '{}{}'.format(name, Class))
                 value = domain[key]
                 if not value:
                     continue
@@ -29,33 +29,33 @@ class Style:
     def __setstate__(self, state):
         self.__init__(**state)
 
-yaml.add_path_resolver(u'tag:yaml.org,2002:python/object:__main__.Style',
+yaml.add_path_resolver('tag:yaml.org,2002:python/object:__main__.Style',
         [None], dict)
-yaml.add_path_resolver(u'tag:yaml.org,2002:pairs',
-        [None, u'replaces'], list)
+yaml.add_path_resolver('tag:yaml.org,2002:pairs',
+        [None, 'replaces'], list)
 
 class YAMLHighlight:
 
     def __init__(self, options):
-        config = yaml.load(file(options.config, 'rb').read())
+        config = yaml.load(open(options.config, 'rb').read())
         self.style = config[options.style]
         if options.input:
-            self.input = file(options.input, 'rb')
+            self.input = open(options.input, 'rb')
         else:
             self.input = sys.stdin
         if options.output:
-            self.output = file(options.output, 'wb')
+            self.output = open(options.output, 'wb')
         else:
             self.output = sys.stdout
 
     def highlight(self):
         input = self.input.read()
         if input.startswith(codecs.BOM_UTF16_LE):
-            input = unicode(input, 'utf-16-le')
+            input = str(input, 'utf-16-le')
         elif input.startswith(codecs.BOM_UTF16_BE):
-            input = unicode(input, 'utf-16-be')
+            input = str(input, 'utf-16-be')
         else:
-            input = unicode(input, 'utf-8')
+            input = str(input, 'utf-8')
         substitutions = self.style.substitutions
         tokens = yaml.scan(input)
         events = yaml.parse(input)
@@ -90,7 +90,7 @@ class YAMLHighlight:
                 position = index
             chunks.append(substitution)
         chunks.reverse()
-        result = u''.join(chunks)
+        result = ''.join(chunks)
         if self.style.header:
             self.output.write(self.style.header)
         self.output.write(result.encode('utf-8'))
diff --git a/python/pyyaml/lib/yaml/__init__.py b/python/pyyaml/lib/yaml/__init__.py
index 76e19e13f1..8420f0ac1b 100644
--- a/python/pyyaml/lib/yaml/__init__.py
+++ b/python/pyyaml/lib/yaml/__init__.py
@@ -1,17 +1,17 @@
+from .error import *
 
-from error import *
+from .tokens import *
+from .events import *
+from .nodes import *
 
-from tokens import *
-from events import *
-from nodes import *
-
-from loader import *
-from dumper import *
+from .loader import *
+from .dumper import *
+import six
 
 __version__ = '3.11'
 
 try:
-    from cyaml import *
+    from .cyaml import *
     __with_libyaml__ = True
 except ImportError:
     __with_libyaml__ = False
@@ -278,18 +278,16 @@ class YAMLObjectMetaclass(type):
     The metaclass for YAMLObject.
     """
     def __init__(cls, name, bases, kwds):
-        super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds)
+        super().__init__(name, bases, kwds)
         if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
             cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
             cls.yaml_dumper.add_representer(cls, cls.to_yaml)
 
-class YAMLObject(object):
+class YAMLObject(six.with_metaclass(YAMLObjectMetaclass)):
     """
     An object that can dump itself to a YAML stream
     and load itself from a YAML stream.
     """
-
-    __metaclass__ = YAMLObjectMetaclass
     __slots__ = ()  # no direct instantiation, so allow immutable subclasses
 
     yaml_loader = Loader
diff --git a/python/pyyaml/lib/yaml/composer.py b/python/pyyaml/lib/yaml/composer.py
index 06e5ac782f..1cc6224505 100644
--- a/python/pyyaml/lib/yaml/composer.py
+++ b/python/pyyaml/lib/yaml/composer.py
@@ -1,14 +1,13 @@
-
 __all__ = ['Composer', 'ComposerError']
 
-from error import MarkedYAMLError
-from events import *
-from nodes import *
+from .error import MarkedYAMLError
+from .events import *
+from .nodes import *
 
 class ComposerError(MarkedYAMLError):
     pass
 
-class Composer(object):
+class Composer:
 
     def __init__(self):
         self.anchors = {}
@@ -88,7 +87,7 @@ class Composer(object):
     def compose_scalar_node(self, anchor):
         event = self.get_event()
         tag = event.tag
-        if tag is None or tag == u'!':
+        if tag is None or tag == '!':
             tag = self.resolve(ScalarNode, event.value, event.implicit)
         node = ScalarNode(tag, event.value,
                 event.start_mark, event.end_mark, style=event.style)
@@ -99,7 +98,7 @@ class Composer(object):
     def compose_sequence_node(self, anchor):
         start_event = self.get_event()
         tag = start_event.tag
-        if tag is None or tag == u'!':
+        if tag is None or tag == '!':
             tag = self.resolve(SequenceNode, None, start_event.implicit)
         node = SequenceNode(tag, [],
                 start_event.start_mark, None,
@@ -117,7 +116,7 @@ class Composer(object):
     def compose_mapping_node(self, anchor):
         start_event = self.get_event()
         tag = start_event.tag
-        if tag is None or tag == u'!':
+        if tag is None or tag == '!':
             tag = self.resolve(MappingNode, None, start_event.implicit)
         node = MappingNode(tag, [],
                 start_event.start_mark, None,
diff --git a/python/pyyaml/lib/yaml/constructor.py b/python/pyyaml/lib/yaml/constructor.py
index 635faac3e6..f689747678 100644
--- a/python/pyyaml/lib/yaml/constructor.py
+++ b/python/pyyaml/lib/yaml/constructor.py
@@ -1,9 +1,8 @@
-
 __all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
     'ConstructorError']
 
-from error import *
-from nodes import *
+from .error import *
+from .nodes import *
 
 import datetime
 
@@ -90,7 +89,7 @@ class BaseConstructor(object):
             data = constructor(self, tag_suffix, node)
         if isinstance(data, types.GeneratorType):
             generator = data
-            data = generator.next()
+            data = next(generator)
             if self.deep_construct:
                 for dummy in generator:
                     pass
@@ -127,7 +126,7 @@ class BaseConstructor(object):
             key = self.construct_object(key_node, deep=deep)
             try:
                 hash(key)
-            except TypeError, exc:
+            except TypeError as exc:
                 raise ConstructorError("while constructing a mapping", node.start_mark,
                         "found unacceptable key (%s)" % exc, key_node.start_mark)
             value = self.construct_object(value_node, deep=deep)
@@ -163,7 +162,7 @@ class SafeConstructor(BaseConstructor):
     def construct_scalar(self, node):
         if isinstance(node, MappingNode):
             for key_node, value_node in node.value:
-                if key_node.tag == u'tag:yaml.org,2002:value':
+                if key_node.tag == 'tag:yaml.org,2002:value':
                     return self.construct_scalar(value_node)
         return BaseConstructor.construct_scalar(self, node)
 
@@ -172,7 +171,7 @@ class SafeConstructor(BaseConstructor):
         index = 0
         while index < len(node.value):
             key_node, value_node = node.value[index]
-            if key_node.tag == u'tag:yaml.org,2002:merge':
+            if key_node.tag == 'tag:yaml.org,2002:merge':
                 del node.value[index]
                 if isinstance(value_node, MappingNode):
                     self.flatten_mapping(value_node)
@@ -194,8 +193,8 @@ class SafeConstructor(BaseConstructor):
                     raise ConstructorError("while constructing a mapping", node.start_mark,
                             "expected a mapping or list of mappings for merging, but found %s"
                             % value_node.id, value_node.start_mark)
-            elif key_node.tag == u'tag:yaml.org,2002:value':
-                key_node.tag = u'tag:yaml.org,2002:str'
+            elif key_node.tag == 'tag:yaml.org,2002:value':
+                key_node.tag = 'tag:yaml.org,2002:str'
                 index += 1
             else:
                 index += 1
@@ -212,12 +211,12 @@ class SafeConstructor(BaseConstructor):
         return None
 
     bool_values = {
-        u'yes':     True,
-        u'no':      False,
-        u'true':    True,
-        u'false':   False,
-        u'on':      True,
-        u'off':     False,
+        'yes':     True,
+        'no':      False,
+        'true':    True,
+        'false':   False,
+        'on':      True,
+        'off':     False,
     }
 
     def construct_yaml_bool(self, node):
@@ -285,19 +284,19 @@ class SafeConstructor(BaseConstructor):
         value = self.construct_scalar(node)
         try:
             return str(value).decode('base64')
-        except (binascii.Error, UnicodeEncodeError), exc:
+        except (binascii.Error, UnicodeEncodeError) as exc:
             raise ConstructorError(None, None,
                     "failed to decode base64 data: %s" % exc, node.start_mark) 
 
     timestamp_regexp = re.compile(
-            ur'''^(?P[0-9][0-9][0-9][0-9])
+            r'''^(?P[0-9][0-9][0-9][0-9])
                 -(?P[0-9][0-9]?)
                 -(?P[0-9][0-9]?)
                 (?:(?:[Tt]|[ \t]+)
                 (?P[0-9][0-9]?)
                 :(?P[0-9][0-9])
                 :(?P[0-9][0-9])
-                (?:\.(?P[0-9]*))?
+                (?:\\.(?P[0-9]*))?
                 (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?)
                 (?::(?P[0-9][0-9]))?))?)?$''', re.X)
 
@@ -414,51 +413,51 @@ class SafeConstructor(BaseConstructor):
                 node.start_mark)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:null',
+        'tag:yaml.org,2002:null',
         SafeConstructor.construct_yaml_null)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:bool',
+        'tag:yaml.org,2002:bool',
         SafeConstructor.construct_yaml_bool)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:int',
+        'tag:yaml.org,2002:int',
         SafeConstructor.construct_yaml_int)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:float',
+        'tag:yaml.org,2002:float',
         SafeConstructor.construct_yaml_float)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:binary',
+        'tag:yaml.org,2002:binary',
         SafeConstructor.construct_yaml_binary)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:timestamp',
+        'tag:yaml.org,2002:timestamp',
         SafeConstructor.construct_yaml_timestamp)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:omap',
+        'tag:yaml.org,2002:omap',
         SafeConstructor.construct_yaml_omap)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:pairs',
+        'tag:yaml.org,2002:pairs',
         SafeConstructor.construct_yaml_pairs)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:set',
+        'tag:yaml.org,2002:set',
         SafeConstructor.construct_yaml_set)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:str',
+        'tag:yaml.org,2002:str',
         SafeConstructor.construct_yaml_str)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:seq',
+        'tag:yaml.org,2002:seq',
         SafeConstructor.construct_yaml_seq)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:map',
+        'tag:yaml.org,2002:map',
         SafeConstructor.construct_yaml_map)
 
 SafeConstructor.add_constructor(None,
@@ -473,7 +472,7 @@ class Constructor(SafeConstructor):
         return self.construct_scalar(node)
 
     def construct_python_long(self, node):
-        return long(self.construct_yaml_int(node))
+        return int(self.construct_yaml_int(node))
 
     def construct_python_complex(self, node):
        return complex(self.construct_scalar(node))
@@ -487,7 +486,7 @@ class Constructor(SafeConstructor):
                     "expected non-empty name appended to the tag", mark)
         try:
             __import__(name)
-        except ImportError, exc:
+        except ImportError as exc:
             raise ConstructorError("while constructing a Python module", mark,
                     "cannot find module %r (%s)" % (name.encode('utf-8'), exc), mark)
         return sys.modules[name]
@@ -496,14 +495,14 @@ class Constructor(SafeConstructor):
         if not name:
             raise ConstructorError("while constructing a Python object", mark,
                     "expected non-empty name appended to the tag", mark)
-        if u'.' in name:
+        if '.' in name:
             module_name, object_name = name.rsplit('.', 1)
         else:
             module_name = '__builtin__'
             object_name = name
         try:
             __import__(module_name)
-        except ImportError, exc:
+        except ImportError as exc:
             raise ConstructorError("while constructing a Python object", mark,
                     "cannot find module %r (%s)" % (module_name.encode('utf-8'), exc), mark)
         module = sys.modules[module_name]
@@ -610,66 +609,66 @@ class Constructor(SafeConstructor):
         return self.construct_python_object_apply(suffix, node, newobj=True)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/none',
+    'tag:yaml.org,2002:python/none',
     Constructor.construct_yaml_null)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/bool',
+    'tag:yaml.org,2002:python/bool',
     Constructor.construct_yaml_bool)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/str',
+    'tag:yaml.org,2002:python/str',
     Constructor.construct_python_str)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/unicode',
+    'tag:yaml.org,2002:python/unicode',
     Constructor.construct_python_unicode)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/int',
+    'tag:yaml.org,2002:python/int',
     Constructor.construct_yaml_int)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/long',
+    'tag:yaml.org,2002:python/long',
     Constructor.construct_python_long)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/float',
+    'tag:yaml.org,2002:python/float',
     Constructor.construct_yaml_float)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/complex',
+    'tag:yaml.org,2002:python/complex',
     Constructor.construct_python_complex)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/list',
+    'tag:yaml.org,2002:python/list',
     Constructor.construct_yaml_seq)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/tuple',
+    'tag:yaml.org,2002:python/tuple',
     Constructor.construct_python_tuple)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/dict',
+    'tag:yaml.org,2002:python/dict',
     Constructor.construct_yaml_map)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/name:',
+    'tag:yaml.org,2002:python/name:',
     Constructor.construct_python_name)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/module:',
+    'tag:yaml.org,2002:python/module:',
     Constructor.construct_python_module)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/object:',
+    'tag:yaml.org,2002:python/object:',
     Constructor.construct_python_object)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/object/apply:',
+    'tag:yaml.org,2002:python/object/apply:',
     Constructor.construct_python_object_apply)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/object/new:',
+    'tag:yaml.org,2002:python/object/new:',
     Constructor.construct_python_object_new)
 
diff --git a/python/pyyaml/lib/yaml/cyaml.py b/python/pyyaml/lib/yaml/cyaml.py
index 68dcd75192..0baa920d40 100644
--- a/python/pyyaml/lib/yaml/cyaml.py
+++ b/python/pyyaml/lib/yaml/cyaml.py
@@ -1,15 +1,14 @@
-
 __all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader',
         'CBaseDumper', 'CSafeDumper', 'CDumper']
 
 from _yaml import CParser, CEmitter
 
-from constructor import *
+from .constructor import *
 
-from serializer import *
-from representer import *
+from .serializer import *
+from .representer import *
 
-from resolver import *
+from .resolver import *
 
 class CBaseLoader(CParser, BaseConstructor, BaseResolver):
 
diff --git a/python/pyyaml/lib/yaml/dumper.py b/python/pyyaml/lib/yaml/dumper.py
index f811d2c919..dfd8c7cf36 100644
--- a/python/pyyaml/lib/yaml/dumper.py
+++ b/python/pyyaml/lib/yaml/dumper.py
@@ -1,10 +1,9 @@
-
 __all__ = ['BaseDumper', 'SafeDumper', 'Dumper']
 
-from emitter import *
-from serializer import *
-from representer import *
-from resolver import *
+from .emitter import *
+from .serializer import *
+from .representer import *
+from .resolver import *
 
 class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
 
diff --git a/python/pyyaml/lib/yaml/emitter.py b/python/pyyaml/lib/yaml/emitter.py
index e5bcdcccbb..4e5c244850 100644
--- a/python/pyyaml/lib/yaml/emitter.py
+++ b/python/pyyaml/lib/yaml/emitter.py
@@ -1,4 +1,3 @@
-
 # Emitter expects events obeying the following grammar:
 # stream ::= STREAM-START document* STREAM-END
 # document ::= DOCUMENT-START node DOCUMENT-END
@@ -8,13 +7,13 @@
 
 __all__ = ['Emitter', 'EmitterError']
 
-from error import YAMLError
-from events import *
+from .error import YAMLError
+from .events import *
 
 class EmitterError(YAMLError):
     pass
 
-class ScalarAnalysis(object):
+class ScalarAnalysis:
     def __init__(self, scalar, empty, multiline,
             allow_flow_plain, allow_block_plain,
             allow_single_quoted, allow_double_quoted,
@@ -28,11 +27,11 @@ class ScalarAnalysis(object):
         self.allow_double_quoted = allow_double_quoted
         self.allow_block = allow_block
 
-class Emitter(object):
+class Emitter:
 
     DEFAULT_TAG_PREFIXES = {
-        u'!' : u'!',
-        u'tag:yaml.org,2002:' : u'!!',
+        '!' : '!',
+        'tag:yaml.org,2002:' : '!!',
     }
 
     def __init__(self, stream, canonical=None, indent=None, width=None,
@@ -88,8 +87,8 @@ class Emitter(object):
         self.best_width = 80
         if width and width > self.best_indent*2:
             self.best_width = width
-        self.best_line_break = u'\n'
-        if line_break in [u'\r', u'\n', u'\r\n']:
+        self.best_line_break = '\n'
+        if line_break in ['\r', '\n', '\r\n']:
             self.best_line_break = line_break
 
         # Tag prefixes.
@@ -178,14 +177,14 @@ class Emitter(object):
     def expect_document_start(self, first=False):
         if isinstance(self.event, DocumentStartEvent):
             if (self.event.version or self.event.tags) and self.open_ended:
-                self.write_indicator(u'...', True)
+                self.write_indicator('...', True)
                 self.write_indent()
             if self.event.version:
                 version_text = self.prepare_version(self.event.version)
                 self.write_version_directive(version_text)
             self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy()
             if self.event.tags:
-                handles = self.event.tags.keys()
+                handles = list(self.event.tags.keys())
                 handles.sort()
                 for handle in handles:
                     prefix = self.event.tags[handle]
@@ -198,13 +197,13 @@ class Emitter(object):
                     and not self.check_empty_document())
             if not implicit:
                 self.write_indent()
-                self.write_indicator(u'---', True)
+                self.write_indicator('---', True)
                 if self.canonical:
                     self.write_indent()
             self.state = self.expect_document_root
         elif isinstance(self.event, StreamEndEvent):
             if self.open_ended:
-                self.write_indicator(u'...', True)
+                self.write_indicator('...', True)
                 self.write_indent()
             self.write_stream_end()
             self.state = self.expect_nothing
@@ -216,7 +215,7 @@ class Emitter(object):
         if isinstance(self.event, DocumentEndEvent):
             self.write_indent()
             if self.event.explicit:
-                self.write_indicator(u'...', True)
+                self.write_indicator('...', True)
                 self.write_indent()
             self.flush_stream()
             self.state = self.expect_document_start
@@ -239,7 +238,7 @@ class Emitter(object):
         if isinstance(self.event, AliasEvent):
             self.expect_alias()
         elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)):
-            self.process_anchor(u'&')
+            self.process_anchor('&')
             self.process_tag()
             if isinstance(self.event, ScalarEvent):
                 self.expect_scalar()
@@ -261,7 +260,7 @@ class Emitter(object):
     def expect_alias(self):
         if self.event.anchor is None:
             raise EmitterError("anchor is not specified for alias")
-        self.process_anchor(u'*')
+        self.process_anchor('*')
         self.state = self.states.pop()
 
     def expect_scalar(self):
@@ -273,7 +272,7 @@ class Emitter(object):
     # Flow sequence handlers.
 
     def expect_flow_sequence(self):
-        self.write_indicator(u'[', True, whitespace=True)
+        self.write_indicator('[', True, whitespace=True)
         self.flow_level += 1
         self.increase_indent(flow=True)
         self.state = self.expect_first_flow_sequence_item
@@ -282,7 +281,7 @@ class Emitter(object):
         if isinstance(self.event, SequenceEndEvent):
             self.indent = self.indents.pop()
             self.flow_level -= 1
-            self.write_indicator(u']', False)
+            self.write_indicator(']', False)
             self.state = self.states.pop()
         else:
             if self.canonical or self.column > self.best_width:
@@ -295,12 +294,12 @@ class Emitter(object):
             self.indent = self.indents.pop()
             self.flow_level -= 1
             if self.canonical:
-                self.write_indicator(u',', False)
+                self.write_indicator(',', False)
                 self.write_indent()
-            self.write_indicator(u']', False)
+            self.write_indicator(']', False)
             self.state = self.states.pop()
         else:
-            self.write_indicator(u',', False)
+            self.write_indicator(',', False)
             if self.canonical or self.column > self.best_width:
                 self.write_indent()
             self.states.append(self.expect_flow_sequence_item)
@@ -309,7 +308,7 @@ class Emitter(object):
     # Flow mapping handlers.
 
     def expect_flow_mapping(self):
-        self.write_indicator(u'{', True, whitespace=True)
+        self.write_indicator('{', True, whitespace=True)
         self.flow_level += 1
         self.increase_indent(flow=True)
         self.state = self.expect_first_flow_mapping_key
@@ -318,7 +317,7 @@ class Emitter(object):
         if isinstance(self.event, MappingEndEvent):
             self.indent = self.indents.pop()
             self.flow_level -= 1
-            self.write_indicator(u'}', False)
+            self.write_indicator('}', False)
             self.state = self.states.pop()
         else:
             if self.canonical or self.column > self.best_width:
@@ -327,7 +326,7 @@ class Emitter(object):
                 self.states.append(self.expect_flow_mapping_simple_value)
                 self.expect_node(mapping=True, simple_key=True)
             else:
-                self.write_indicator(u'?', True)
+                self.write_indicator('?', True)
                 self.states.append(self.expect_flow_mapping_value)
                 self.expect_node(mapping=True)
 
@@ -336,31 +335,31 @@ class Emitter(object):
             self.indent = self.indents.pop()
             self.flow_level -= 1
             if self.canonical:
-                self.write_indicator(u',', False)
+                self.write_indicator(',', False)
                 self.write_indent()
-            self.write_indicator(u'}', False)
+            self.write_indicator('}', False)
             self.state = self.states.pop()
         else:
-            self.write_indicator(u',', False)
+            self.write_indicator(',', False)
             if self.canonical or self.column > self.best_width:
                 self.write_indent()
             if not self.canonical and self.check_simple_key():
                 self.states.append(self.expect_flow_mapping_simple_value)
                 self.expect_node(mapping=True, simple_key=True)
             else:
-                self.write_indicator(u'?', True)
+                self.write_indicator('?', True)
                 self.states.append(self.expect_flow_mapping_value)
                 self.expect_node(mapping=True)
 
     def expect_flow_mapping_simple_value(self):
-        self.write_indicator(u':', False)
+        self.write_indicator(':', False)
         self.states.append(self.expect_flow_mapping_key)
         self.expect_node(mapping=True)
 
     def expect_flow_mapping_value(self):
         if self.canonical or self.column > self.best_width:
             self.write_indent()
-        self.write_indicator(u':', True)
+        self.write_indicator(':', True)
         self.states.append(self.expect_flow_mapping_key)
         self.expect_node(mapping=True)
 
@@ -380,7 +379,7 @@ class Emitter(object):
             self.state = self.states.pop()
         else:
             self.write_indent()
-            self.write_indicator(u'-', True, indention=True)
+            self.write_indicator('-', True, indention=True)
             self.states.append(self.expect_block_sequence_item)
             self.expect_node(sequence=True)
 
@@ -403,18 +402,18 @@ class Emitter(object):
                 self.states.append(self.expect_block_mapping_simple_value)
                 self.expect_node(mapping=True, simple_key=True)
             else:
-                self.write_indicator(u'?', True, indention=True)
+                self.write_indicator('?', True, indention=True)
                 self.states.append(self.expect_block_mapping_value)
                 self.expect_node(mapping=True)
 
     def expect_block_mapping_simple_value(self):
-        self.write_indicator(u':', False)
+        self.write_indicator(':', False)
         self.states.append(self.expect_block_mapping_key)
         self.expect_node(mapping=True)
 
     def expect_block_mapping_value(self):
         self.write_indent()
-        self.write_indicator(u':', True, indention=True)
+        self.write_indicator(':', True, indention=True)
         self.states.append(self.expect_block_mapping_key)
         self.expect_node(mapping=True)
 
@@ -433,7 +432,7 @@ class Emitter(object):
             return False
         event = self.events[0]
         return (isinstance(event, ScalarEvent) and event.anchor is None
-                and event.tag is None and event.implicit and event.value == u'')
+                and event.tag is None and event.implicit and event.value == '')
 
     def check_simple_key(self):
         length = 0
@@ -478,7 +477,7 @@ class Emitter(object):
                 self.prepared_tag = None
                 return
             if self.event.implicit[0] and tag is None:
-                tag = u'!'
+                tag = '!'
                 self.prepared_tag = None
         else:
             if (not self.canonical or tag is None) and self.event.implicit:
@@ -541,17 +540,17 @@ class Emitter(object):
         major, minor = version
         if major != 1:
             raise EmitterError("unsupported YAML version: %d.%d" % (major, minor))
-        return u'%d.%d' % (major, minor)
+        return '%d.%d' % (major, minor)
 
     def prepare_tag_handle(self, handle):
         if not handle:
             raise EmitterError("tag handle must not be empty")
-        if handle[0] != u'!' or handle[-1] != u'!':
+        if handle[0] != '!' or handle[-1] != '!':
             raise EmitterError("tag handle must start and end with '!': %r"
                     % (handle.encode('utf-8')))
         for ch in handle[1:-1]:
-            if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'  \
-                    or ch in u'-_'):
+            if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                    or ch in '-_'):
                 raise EmitterError("invalid character %r in the tag handle: %r"
                         % (ch.encode('utf-8'), handle.encode('utf-8')))
         return handle
@@ -561,12 +560,12 @@ class Emitter(object):
             raise EmitterError("tag prefix must not be empty")
         chunks = []
         start = end = 0
-        if prefix[0] == u'!':
+        if prefix[0] == '!':
             end = 1
         while end < len(prefix):
             ch = prefix[end]
-            if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'   \
-                    or ch in u'-;/?!:@&=+$,_.~*\'()[]':
+            if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'   \
+                    or ch in '-;/?!:@&=+$,_.~*\'()[]':
                 end += 1
             else:
                 if start < end:
@@ -574,32 +573,32 @@ class Emitter(object):
                 start = end = end+1
                 data = ch.encode('utf-8')
                 for ch in data:
-                    chunks.append(u'%%%02X' % ord(ch))
+                    chunks.append('%%%02X' % ord(ch))
         if start < end:
             chunks.append(prefix[start:end])
-        return u''.join(chunks)
+        return ''.join(chunks)
 
     def prepare_tag(self, tag):
         if not tag:
             raise EmitterError("tag must not be empty")
-        if tag == u'!':
+        if tag == '!':
             return tag
         handle = None
         suffix = tag
-        prefixes = self.tag_prefixes.keys()
+        prefixes = list(self.tag_prefixes.keys())
         prefixes.sort()
         for prefix in prefixes:
             if tag.startswith(prefix)   \
-                    and (prefix == u'!' or len(prefix) < len(tag)):
+                    and (prefix == '!' or len(prefix) < len(tag)):
                 handle = self.tag_prefixes[prefix]
                 suffix = tag[len(prefix):]
         chunks = []
         start = end = 0
         while end < len(suffix):
             ch = suffix[end]
-            if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'   \
-                    or ch in u'-;/?:@&=+$,_.~*\'()[]'   \
-                    or (ch == u'!' and handle != u'!'):
+            if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'   \
+                    or ch in '-;/?:@&=+$,_.~*\'()[]'   \
+                    or (ch == '!' and handle != '!'):
                 end += 1
             else:
                 if start < end:
@@ -607,21 +606,21 @@ class Emitter(object):
                 start = end = end+1
                 data = ch.encode('utf-8')
                 for ch in data:
-                    chunks.append(u'%%%02X' % ord(ch))
+                    chunks.append('%%%02X' % ord(ch))
         if start < end:
             chunks.append(suffix[start:end])
-        suffix_text = u''.join(chunks)
+        suffix_text = ''.join(chunks)
         if handle:
-            return u'%s%s' % (handle, suffix_text)
+            return '{}{}'.format(handle, suffix_text)
         else:
-            return u'!<%s>' % suffix_text
+            return '!<%s>' % suffix_text
 
     def prepare_anchor(self, anchor):
         if not anchor:
             raise EmitterError("anchor must not be empty")
         for ch in anchor:
-            if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'  \
-                    or ch in u'-_'):
+            if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                    or ch in '-_'):
                 raise EmitterError("invalid character %r in the anchor: %r"
                         % (ch.encode('utf-8'), anchor.encode('utf-8')))
         return anchor
@@ -650,7 +649,7 @@ class Emitter(object):
         space_break = False
 
         # Check document indicators.
-        if scalar.startswith(u'---') or scalar.startswith(u'...'):
+        if scalar.startswith('---') or scalar.startswith('...'):
             block_indicators = True
             flow_indicators = True
 
@@ -659,7 +658,7 @@ class Emitter(object):
 
         # Last character or followed by a whitespace.
         followed_by_whitespace = (len(scalar) == 1 or
-                scalar[1] in u'\0 \t\r\n\x85\u2028\u2029')
+                scalar[1] in '\0 \t\r\n\x85\u2028\u2029')
 
         # The previous character is a space.
         previous_space = False
@@ -674,34 +673,34 @@ class Emitter(object):
             # Check for indicators.
             if index == 0:
                 # Leading indicators are special characters.
-                if ch in u'#,[]{}&*!|>\'\"%@`': 
+                if ch in '#,[]{}&*!|>\'\"%@`': 
                     flow_indicators = True
                     block_indicators = True
-                if ch in u'?:':
+                if ch in '?:':
                     flow_indicators = True
                     if followed_by_whitespace:
                         block_indicators = True
-                if ch == u'-' and followed_by_whitespace:
+                if ch == '-' and followed_by_whitespace:
                     flow_indicators = True
                     block_indicators = True
             else:
                 # Some indicators cannot appear within a scalar as well.
-                if ch in u',?[]{}':
+                if ch in ',?[]{}':
                     flow_indicators = True
-                if ch == u':':
+                if ch == ':':
                     flow_indicators = True
                     if followed_by_whitespace:
                         block_indicators = True
-                if ch == u'#' and preceeded_by_whitespace:
+                if ch == '#' and preceeded_by_whitespace:
                     flow_indicators = True
                     block_indicators = True
 
             # Check for line breaks, special, and unicode characters.
-            if ch in u'\n\x85\u2028\u2029':
+            if ch in '\n\x85\u2028\u2029':
                 line_breaks = True
-            if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'):
-                if (ch == u'\x85' or u'\xA0' <= ch <= u'\uD7FF'
-                        or u'\uE000' <= ch <= u'\uFFFD') and ch != u'\uFEFF':
+            if not (ch == '\n' or '\x20' <= ch <= '\x7E'):
+                if (ch == '\x85' or '\xA0' <= ch <= '\uD7FF'
+                        or '\uE000' <= ch <= '\uFFFD') and ch != '\uFEFF':
                     unicode_characters = True
                     if not self.allow_unicode:
                         special_characters = True
@@ -709,7 +708,7 @@ class Emitter(object):
                     special_characters = True
 
             # Detect important whitespace combinations.
-            if ch == u' ':
+            if ch == ' ':
                 if index == 0:
                     leading_space = True
                 if index == len(scalar)-1:
@@ -718,7 +717,7 @@ class Emitter(object):
                     break_space = True
                 previous_space = True
                 previous_break = False
-            elif ch in u'\n\x85\u2028\u2029':
+            elif ch in '\n\x85\u2028\u2029':
                 if index == 0:
                     leading_break = True
                 if index == len(scalar)-1:
@@ -733,9 +732,9 @@ class Emitter(object):
 
             # Prepare for the next character.
             index += 1
-            preceeded_by_whitespace = (ch in u'\0 \t\r\n\x85\u2028\u2029')
+            preceeded_by_whitespace = (ch in '\0 \t\r\n\x85\u2028\u2029')
             followed_by_whitespace = (index+1 >= len(scalar) or
-                    scalar[index+1] in u'\0 \t\r\n\x85\u2028\u2029')
+                    scalar[index+1] in '\0 \t\r\n\x85\u2028\u2029')
 
         # Let's decide what styles are allowed.
         allow_flow_plain = True
@@ -794,7 +793,7 @@ class Emitter(object):
     def write_stream_start(self):
         # Write BOM if needed.
         if self.encoding and self.encoding.startswith('utf-16'):
-            self.stream.write(u'\uFEFF'.encode(self.encoding))
+            self.stream.write('\uFEFF'.encode(self.encoding))
 
     def write_stream_end(self):
         self.flush_stream()
@@ -804,7 +803,7 @@ class Emitter(object):
         if self.whitespace or not need_whitespace:
             data = indicator
         else:
-            data = u' '+indicator
+            data = ' '+indicator
         self.whitespace = whitespace
         self.indention = self.indention and indention
         self.column += len(data)
@@ -820,7 +819,7 @@ class Emitter(object):
             self.write_line_break()
         if self.column < indent:
             self.whitespace = True
-            data = u' '*(indent-self.column)
+            data = ' '*(indent-self.column)
             self.column = indent
             if self.encoding:
                 data = data.encode(self.encoding)
@@ -838,14 +837,14 @@ class Emitter(object):
         self.stream.write(data)
 
     def write_version_directive(self, version_text):
-        data = u'%%YAML %s' % version_text
+        data = '%%YAML %s' % version_text
         if self.encoding:
             data = data.encode(self.encoding)
         self.stream.write(data)
         self.write_line_break()
 
     def write_tag_directive(self, handle_text, prefix_text):
-        data = u'%%TAG %s %s' % (handle_text, prefix_text)
+        data = '%TAG {} {}'.format(handle_text, prefix_text)
         if self.encoding:
             data = data.encode(self.encoding)
         self.stream.write(data)
@@ -854,7 +853,7 @@ class Emitter(object):
     # Scalar streams.
 
     def write_single_quoted(self, text, split=True):
-        self.write_indicator(u'\'', True)
+        self.write_indicator('\'', True)
         spaces = False
         breaks = False
         start = end = 0
@@ -863,7 +862,7 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if spaces:
-                if ch is None or ch != u' ':
+                if ch is None or ch != ' ':
                     if start+1 == end and self.column > self.best_width and split   \
                             and start != 0 and end != len(text):
                         self.write_indent()
@@ -875,18 +874,18 @@ class Emitter(object):
                         self.stream.write(data)
                     start = end
             elif breaks:
-                if ch is None or ch not in u'\n\x85\u2028\u2029':
-                    if text[start] == u'\n':
+                if ch is None or ch not in '\n\x85\u2028\u2029':
+                    if text[start] == '\n':
                         self.write_line_break()
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
                     self.write_indent()
                     start = end
             else:
-                if ch is None or ch in u' \n\x85\u2028\u2029' or ch == u'\'':
+                if ch is None or ch in ' \n\x85\u2028\u2029' or ch == '\'':
                     if start < end:
                         data = text[start:end]
                         self.column += len(data)
@@ -894,49 +893,49 @@ class Emitter(object):
                             data = data.encode(self.encoding)
                         self.stream.write(data)
                         start = end
-            if ch == u'\'':
-                data = u'\'\''
+            if ch == '\'':
+                data = '\'\''
                 self.column += 2
                 if self.encoding:
                     data = data.encode(self.encoding)
                 self.stream.write(data)
                 start = end + 1
             if ch is not None:
-                spaces = (ch == u' ')
-                breaks = (ch in u'\n\x85\u2028\u2029')
+                spaces = (ch == ' ')
+                breaks = (ch in '\n\x85\u2028\u2029')
             end += 1
-        self.write_indicator(u'\'', False)
+        self.write_indicator('\'', False)
 
     ESCAPE_REPLACEMENTS = {
-        u'\0':      u'0',
-        u'\x07':    u'a',
-        u'\x08':    u'b',
-        u'\x09':    u't',
-        u'\x0A':    u'n',
-        u'\x0B':    u'v',
-        u'\x0C':    u'f',
-        u'\x0D':    u'r',
-        u'\x1B':    u'e',
-        u'\"':      u'\"',
-        u'\\':      u'\\',
-        u'\x85':    u'N',
-        u'\xA0':    u'_',
-        u'\u2028':  u'L',
-        u'\u2029':  u'P',
+        '\0':      '0',
+        '\x07':    'a',
+        '\x08':    'b',
+        '\x09':    't',
+        '\x0A':    'n',
+        '\x0B':    'v',
+        '\x0C':    'f',
+        '\x0D':    'r',
+        '\x1B':    'e',
+        '\"':      '\"',
+        '\\':      '\\',
+        '\x85':    'N',
+        '\xA0':    '_',
+        '\u2028':  'L',
+        '\u2029':  'P',
     }
 
     def write_double_quoted(self, text, split=True):
-        self.write_indicator(u'"', True)
+        self.write_indicator('"', True)
         start = end = 0
         while end <= len(text):
             ch = None
             if end < len(text):
                 ch = text[end]
-            if ch is None or ch in u'"\\\x85\u2028\u2029\uFEFF' \
-                    or not (u'\x20' <= ch <= u'\x7E'
+            if ch is None or ch in '"\\\x85\u2028\u2029\uFEFF' \
+                    or not ('\x20' <= ch <= '\x7E'
                         or (self.allow_unicode
-                            and (u'\xA0' <= ch <= u'\uD7FF'
-                                or u'\uE000' <= ch <= u'\uFFFD'))):
+                            and ('\xA0' <= ch <= '\uD7FF'
+                                or '\uE000' <= ch <= '\uFFFD'))):
                 if start < end:
                     data = text[start:end]
                     self.column += len(data)
@@ -946,21 +945,21 @@ class Emitter(object):
                     start = end
                 if ch is not None:
                     if ch in self.ESCAPE_REPLACEMENTS:
-                        data = u'\\'+self.ESCAPE_REPLACEMENTS[ch]
-                    elif ch <= u'\xFF':
-                        data = u'\\x%02X' % ord(ch)
-                    elif ch <= u'\uFFFF':
-                        data = u'\\u%04X' % ord(ch)
+                        data = '\\'+self.ESCAPE_REPLACEMENTS[ch]
+                    elif ch <= '\xFF':
+                        data = '\\x%02X' % ord(ch)
+                    elif ch <= '\uFFFF':
+                        data = '\\u%04X' % ord(ch)
                     else:
-                        data = u'\\U%08X' % ord(ch)
+                        data = '\\U%08X' % ord(ch)
                     self.column += len(data)
                     if self.encoding:
                         data = data.encode(self.encoding)
                     self.stream.write(data)
                     start = end+1
-            if 0 < end < len(text)-1 and (ch == u' ' or start >= end)   \
+            if 0 < end < len(text)-1 and (ch == ' ' or start >= end)   \
                     and self.column+(end-start) > self.best_width and split:
-                data = text[start:end]+u'\\'
+                data = text[start:end]+'\\'
                 if start < end:
                     start = end
                 self.column += len(data)
@@ -970,30 +969,30 @@ class Emitter(object):
                 self.write_indent()
                 self.whitespace = False
                 self.indention = False
-                if text[start] == u' ':
-                    data = u'\\'
+                if text[start] == ' ':
+                    data = '\\'
                     self.column += len(data)
                     if self.encoding:
                         data = data.encode(self.encoding)
                     self.stream.write(data)
             end += 1
-        self.write_indicator(u'"', False)
+        self.write_indicator('"', False)
 
     def determine_block_hints(self, text):
-        hints = u''
+        hints = ''
         if text:
-            if text[0] in u' \n\x85\u2028\u2029':
-                hints += unicode(self.best_indent)
-            if text[-1] not in u'\n\x85\u2028\u2029':
-                hints += u'-'
-            elif len(text) == 1 or text[-2] in u'\n\x85\u2028\u2029':
-                hints += u'+'
+            if text[0] in ' \n\x85\u2028\u2029':
+                hints += str(self.best_indent)
+            if text[-1] not in '\n\x85\u2028\u2029':
+                hints += '-'
+            elif len(text) == 1 or text[-2] in '\n\x85\u2028\u2029':
+                hints += '+'
         return hints
 
     def write_folded(self, text):
         hints = self.determine_block_hints(text)
-        self.write_indicator(u'>'+hints, True)
-        if hints[-1:] == u'+':
+        self.write_indicator('>'+hints, True)
+        if hints[-1:] == '+':
             self.open_ended = True
         self.write_line_break()
         leading_space = True
@@ -1005,13 +1004,13 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if breaks:
-                if ch is None or ch not in u'\n\x85\u2028\u2029':
-                    if not leading_space and ch is not None and ch != u' '  \
-                            and text[start] == u'\n':
+                if ch is None or ch not in '\n\x85\u2028\u2029':
+                    if not leading_space and ch is not None and ch != ' '  \
+                            and text[start] == '\n':
                         self.write_line_break()
-                    leading_space = (ch == u' ')
+                    leading_space = (ch == ' ')
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
@@ -1019,7 +1018,7 @@ class Emitter(object):
                         self.write_indent()
                     start = end
             elif spaces:
-                if ch != u' ':
+                if ch != ' ':
                     if start+1 == end and self.column > self.best_width:
                         self.write_indent()
                     else:
@@ -1030,7 +1029,7 @@ class Emitter(object):
                         self.stream.write(data)
                     start = end
             else:
-                if ch is None or ch in u' \n\x85\u2028\u2029':
+                if ch is None or ch in ' \n\x85\u2028\u2029':
                     data = text[start:end]
                     self.column += len(data)
                     if self.encoding:
@@ -1040,14 +1039,14 @@ class Emitter(object):
                         self.write_line_break()
                     start = end
             if ch is not None:
-                breaks = (ch in u'\n\x85\u2028\u2029')
-                spaces = (ch == u' ')
+                breaks = (ch in '\n\x85\u2028\u2029')
+                spaces = (ch == ' ')
             end += 1
 
     def write_literal(self, text):
         hints = self.determine_block_hints(text)
-        self.write_indicator(u'|'+hints, True)
-        if hints[-1:] == u'+':
+        self.write_indicator('|'+hints, True)
+        if hints[-1:] == '+':
             self.open_ended = True
         self.write_line_break()
         breaks = True
@@ -1057,9 +1056,9 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if breaks:
-                if ch is None or ch not in u'\n\x85\u2028\u2029':
+                if ch is None or ch not in '\n\x85\u2028\u2029':
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
@@ -1067,7 +1066,7 @@ class Emitter(object):
                         self.write_indent()
                     start = end
             else:
-                if ch is None or ch in u'\n\x85\u2028\u2029':
+                if ch is None or ch in '\n\x85\u2028\u2029':
                     data = text[start:end]
                     if self.encoding:
                         data = data.encode(self.encoding)
@@ -1076,7 +1075,7 @@ class Emitter(object):
                         self.write_line_break()
                     start = end
             if ch is not None:
-                breaks = (ch in u'\n\x85\u2028\u2029')
+                breaks = (ch in '\n\x85\u2028\u2029')
             end += 1
 
     def write_plain(self, text, split=True):
@@ -1085,7 +1084,7 @@ class Emitter(object):
         if not text:
             return
         if not self.whitespace:
-            data = u' '
+            data = ' '
             self.column += len(data)
             if self.encoding:
                 data = data.encode(self.encoding)
@@ -1100,7 +1099,7 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if spaces:
-                if ch != u' ':
+                if ch != ' ':
                     if start+1 == end and self.column > self.best_width and split:
                         self.write_indent()
                         self.whitespace = False
@@ -1113,11 +1112,11 @@ class Emitter(object):
                         self.stream.write(data)
                     start = end
             elif breaks:
-                if ch not in u'\n\x85\u2028\u2029':
-                    if text[start] == u'\n':
+                if ch not in '\n\x85\u2028\u2029':
+                    if text[start] == '\n':
                         self.write_line_break()
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
@@ -1126,7 +1125,7 @@ class Emitter(object):
                     self.indention = False
                     start = end
             else:
-                if ch is None or ch in u' \n\x85\u2028\u2029':
+                if ch is None or ch in ' \n\x85\u2028\u2029':
                     data = text[start:end]
                     self.column += len(data)
                     if self.encoding:
@@ -1134,7 +1133,7 @@ class Emitter(object):
                     self.stream.write(data)
                     start = end
             if ch is not None:
-                spaces = (ch == u' ')
-                breaks = (ch in u'\n\x85\u2028\u2029')
+                spaces = (ch == ' ')
+                breaks = (ch in '\n\x85\u2028\u2029')
             end += 1
 
diff --git a/python/pyyaml/lib/yaml/error.py b/python/pyyaml/lib/yaml/error.py
index 577686db5f..6f7011a2c4 100644
--- a/python/pyyaml/lib/yaml/error.py
+++ b/python/pyyaml/lib/yaml/error.py
@@ -1,7 +1,6 @@
-
 __all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
 
-class Mark(object):
+class Mark:
 
     def __init__(self, name, index, line, column, buffer, pointer):
         self.name = name
@@ -16,7 +15,7 @@ class Mark(object):
             return None
         head = ''
         start = self.pointer
-        while start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029':
+        while start > 0 and self.buffer[start-1] not in '\0\r\n\x85\u2028\u2029':
             start -= 1
             if self.pointer-start > max_length/2-1:
                 head = ' ... '
@@ -24,7 +23,7 @@ class Mark(object):
                 break
         tail = ''
         end = self.pointer
-        while end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029':
+        while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029':
             end += 1
             if end-self.pointer > max_length/2-1:
                 tail = ' ... '
diff --git a/python/pyyaml/lib/yaml/events.py b/python/pyyaml/lib/yaml/events.py
index f79ad389cb..e54499400a 100644
--- a/python/pyyaml/lib/yaml/events.py
+++ b/python/pyyaml/lib/yaml/events.py
@@ -1,16 +1,15 @@
-
 # Abstract classes.
 
-class Event(object):
+class Event:
     def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
     def __repr__(self):
         attributes = [key for key in ['anchor', 'tag', 'implicit', 'value']
                 if hasattr(self, key)]
-        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
+        arguments = ', '.join(['{}={!r}'.format(key, getattr(self, key))
                 for key in attributes])
-        return '%s(%s)' % (self.__class__.__name__, arguments)
+        return '{}({})'.format(self.__class__.__name__, arguments)
 
 class NodeEvent(Event):
     def __init__(self, anchor, start_mark=None, end_mark=None):
diff --git a/python/pyyaml/lib/yaml/loader.py b/python/pyyaml/lib/yaml/loader.py
index 293ff467b1..559275b02a 100644
--- a/python/pyyaml/lib/yaml/loader.py
+++ b/python/pyyaml/lib/yaml/loader.py
@@ -1,12 +1,11 @@
-
 __all__ = ['BaseLoader', 'SafeLoader', 'Loader']
 
-from reader import *
-from scanner import *
-from parser import *
-from composer import *
-from constructor import *
-from resolver import *
+from .reader import *
+from .scanner import *
+from .parser import *
+from .composer import *
+from .constructor import *
+from .resolver import *
 
 class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver):
 
diff --git a/python/pyyaml/lib/yaml/nodes.py b/python/pyyaml/lib/yaml/nodes.py
index c4f070c41e..c9a20df12a 100644
--- a/python/pyyaml/lib/yaml/nodes.py
+++ b/python/pyyaml/lib/yaml/nodes.py
@@ -1,5 +1,4 @@
-
-class Node(object):
+class Node:
     def __init__(self, tag, value, start_mark, end_mark):
         self.tag = tag
         self.value = value
@@ -20,7 +19,7 @@ class Node(object):
         #    else:
         #        value = repr(value)
         value = repr(value)
-        return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value)
+        return '{}(tag={!r}, value={})'.format(self.__class__.__name__, self.tag, value)
 
 class ScalarNode(Node):
     id = 'scalar'
diff --git a/python/pyyaml/lib/yaml/parser.py b/python/pyyaml/lib/yaml/parser.py
index f9e3057f33..2174c21f5c 100644
--- a/python/pyyaml/lib/yaml/parser.py
+++ b/python/pyyaml/lib/yaml/parser.py
@@ -1,4 +1,3 @@
-
 # The following YAML grammar is LL(1) and is parsed by a recursive descent
 # parser.
 #
@@ -61,21 +60,21 @@
 
 __all__ = ['Parser', 'ParserError']
 
-from error import MarkedYAMLError
-from tokens import *
-from events import *
-from scanner import *
+from .error import MarkedYAMLError
+from .tokens import *
+from .events import *
+from .scanner import *
 
 class ParserError(MarkedYAMLError):
     pass
 
-class Parser(object):
+class Parser:
     # Since writing a recursive-descendant parser is a straightforward task, we
     # do not give many comments here.
 
     DEFAULT_TAGS = {
-        u'!':   u'!',
-        u'!!':  u'tag:yaml.org,2002:',
+        '!':   '!',
+        '!!':  'tag:yaml.org,2002:',
     }
 
     def __init__(self):
@@ -219,7 +218,7 @@ class Parser(object):
         self.tag_handles = {}
         while self.check_token(DirectiveToken):
             token = self.get_token()
-            if token.name == u'YAML':
+            if token.name == 'YAML':
                 if self.yaml_version is not None:
                     raise ParserError(None, None,
                             "found duplicate YAML directive", token.start_mark)
@@ -229,7 +228,7 @@ class Parser(object):
                             "found incompatible YAML document (version 1.* is required)",
                             token.start_mark)
                 self.yaml_version = token.value
-            elif token.name == u'TAG':
+            elif token.name == 'TAG':
                 handle, prefix = token.value
                 if handle in self.tag_handles:
                     raise ParserError(None, None,
@@ -315,7 +314,7 @@ class Parser(object):
             if start_mark is None:
                 start_mark = end_mark = self.peek_token().start_mark
             event = None
-            implicit = (tag is None or tag == u'!')
+            implicit = (tag is None or tag == '!')
             if indentless_sequence and self.check_token(BlockEntryToken):
                 end_mark = self.peek_token().end_mark
                 event = SequenceStartEvent(anchor, tag, implicit,
@@ -325,7 +324,7 @@ class Parser(object):
                 if self.check_token(ScalarToken):
                     token = self.get_token()
                     end_mark = token.end_mark
-                    if (token.plain and tag is None) or tag == u'!':
+                    if (token.plain and tag is None) or tag == '!':
                         implicit = (True, False)
                     elif tag is None:
                         implicit = (False, True)
@@ -357,7 +356,7 @@ class Parser(object):
                 elif anchor is not None or tag is not None:
                     # Empty scalars are allowed even if a tag or an anchor is
                     # specified.
-                    event = ScalarEvent(anchor, tag, (implicit, False), u'',
+                    event = ScalarEvent(anchor, tag, (implicit, False), '',
                             start_mark, end_mark)
                     self.state = self.states.pop()
                 else:
@@ -585,5 +584,5 @@ class Parser(object):
         return self.process_empty_scalar(self.peek_token().start_mark)
 
     def process_empty_scalar(self, mark):
-        return ScalarEvent(None, None, (True, False), u'', mark, mark)
+        return ScalarEvent(None, None, (True, False), '', mark, mark)
 
diff --git a/python/pyyaml/lib/yaml/reader.py b/python/pyyaml/lib/yaml/reader.py
index 3249e6b9f5..c6d98ff1a7 100644
--- a/python/pyyaml/lib/yaml/reader.py
+++ b/python/pyyaml/lib/yaml/reader.py
@@ -17,7 +17,7 @@
 
 __all__ = ['Reader', 'ReaderError']
 
-from error import YAMLError, Mark
+from .error import YAMLError, Mark
 
 import codecs, re
 
@@ -61,7 +61,7 @@ class Reader(object):
         self.stream = None
         self.stream_pointer = 0
         self.eof = True
-        self.buffer = u''
+        self.buffer = ''
         self.pointer = 0
         self.raw_buffer = None
         self.raw_decode = None
@@ -69,10 +69,10 @@ class Reader(object):
         self.index = 0
         self.line = 0
         self.column = 0
-        if isinstance(stream, unicode):
+        if isinstance(stream, str):
             self.name = ""
             self.check_printable(stream)
-            self.buffer = stream+u'\0'
+            self.buffer = stream+'\0'
         elif isinstance(stream, str):
             self.name = ""
             self.raw_buffer = stream
@@ -103,11 +103,11 @@ class Reader(object):
             ch = self.buffer[self.pointer]
             self.pointer += 1
             self.index += 1
-            if ch in u'\n\x85\u2028\u2029'  \
-                    or (ch == u'\r' and self.buffer[self.pointer] != u'\n'):
+            if ch in '\n\x85\u2028\u2029'  \
+                    or (ch == '\r' and self.buffer[self.pointer] != '\n'):
                 self.line += 1
                 self.column = 0
-            elif ch != u'\uFEFF':
+            elif ch != '\uFEFF':
                 self.column += 1
             length -= 1
 
@@ -122,7 +122,7 @@ class Reader(object):
     def determine_encoding(self):
         while not self.eof and len(self.raw_buffer) < 2:
             self.update_raw()
-        if not isinstance(self.raw_buffer, unicode):
+        if not isinstance(self.raw_buffer, str):
             if self.raw_buffer.startswith(codecs.BOM_UTF16_LE):
                 self.raw_decode = codecs.utf_16_le_decode
                 self.encoding = 'utf-16-le'
@@ -134,7 +134,7 @@ class Reader(object):
                 self.encoding = 'utf-8'
         self.update(1)
 
-    NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]')
+    NON_PRINTABLE = re.compile('[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]')
     def check_printable(self, data):
         match = self.NON_PRINTABLE.search(data)
         if match:
@@ -155,7 +155,7 @@ class Reader(object):
                 try:
                     data, converted = self.raw_decode(self.raw_buffer,
                             'strict', self.eof)
-                except UnicodeDecodeError, exc:
+                except UnicodeDecodeError as exc:
                     character = exc.object[exc.start]
                     if self.stream is not None:
                         position = self.stream_pointer-len(self.raw_buffer)+exc.start
@@ -170,7 +170,7 @@ class Reader(object):
             self.buffer += data
             self.raw_buffer = self.raw_buffer[converted:]
             if self.eof:
-                self.buffer += u'\0'
+                self.buffer += '\0'
                 self.raw_buffer = None
                 break
 
diff --git a/python/pyyaml/lib/yaml/representer.py b/python/pyyaml/lib/yaml/representer.py
index 5f4fc70dbc..41c08ff892 100644
--- a/python/pyyaml/lib/yaml/representer.py
+++ b/python/pyyaml/lib/yaml/representer.py
@@ -1,18 +1,18 @@
-
+import six
 __all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
     'RepresenterError']
 
-from error import *
-from nodes import *
+from .error import *
+from .nodes import *
 
 import datetime
 
-import sys, copy_reg, types
+import sys, six.moves.copyreg, types
 
 class RepresenterError(YAMLError):
     pass
 
-class BaseRepresenter(object):
+class BaseRepresenter:
 
     yaml_representers = {}
     yaml_multi_representers = {}
@@ -66,7 +66,7 @@ class BaseRepresenter(object):
                 elif None in self.yaml_representers:
                     node = self.yaml_representers[None](self, data)
                 else:
-                    node = ScalarNode(None, unicode(data))
+                    node = ScalarNode(None, str(data))
         #if alias_key is not None:
         #    self.represented_objects[alias_key] = node
         return node
@@ -116,7 +116,7 @@ class BaseRepresenter(object):
             self.represented_objects[self.alias_key] = node
         best_style = True
         if hasattr(mapping, 'items'):
-            mapping = mapping.items()
+            mapping = list(mapping.items())
             mapping.sort()
         for item_key, item_value in mapping:
             node_key = self.represent_data(item_key)
@@ -141,44 +141,44 @@ class SafeRepresenter(BaseRepresenter):
     def ignore_aliases(self, data):
         if data in [None, ()]:
             return True
-        if isinstance(data, (str, unicode, bool, int, float)):
+        if isinstance(data, (str, str, bool, int, float)):
             return True
 
     def represent_none(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:null',
-                u'null')
+        return self.represent_scalar('tag:yaml.org,2002:null',
+                'null')
 
     def represent_str(self, data):
         tag = None
         style = None
         try:
-            data = unicode(data, 'ascii')
-            tag = u'tag:yaml.org,2002:str'
+            data = str(data, 'ascii')
+            tag = 'tag:yaml.org,2002:str'
         except UnicodeDecodeError:
             try:
-                data = unicode(data, 'utf-8')
-                tag = u'tag:yaml.org,2002:str'
+                data = str(data, 'utf-8')
+                tag = 'tag:yaml.org,2002:str'
             except UnicodeDecodeError:
                 data = data.encode('base64')
-                tag = u'tag:yaml.org,2002:binary'
+                tag = 'tag:yaml.org,2002:binary'
                 style = '|'
         return self.represent_scalar(tag, data, style=style)
 
     def represent_unicode(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:str', data)
+        return self.represent_scalar('tag:yaml.org,2002:str', data)
 
     def represent_bool(self, data):
         if data:
-            value = u'true'
+            value = 'true'
         else:
-            value = u'false'
-        return self.represent_scalar(u'tag:yaml.org,2002:bool', value)
+            value = 'false'
+        return self.represent_scalar('tag:yaml.org,2002:bool', value)
 
     def represent_int(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data))
+        return self.represent_scalar('tag:yaml.org,2002:int', str(data))
 
     def represent_long(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data))
+        return self.represent_scalar('tag:yaml.org,2002:int', str(data))
 
     inf_value = 1e300
     while repr(inf_value) != repr(inf_value*inf_value):
@@ -186,13 +186,13 @@ class SafeRepresenter(BaseRepresenter):
 
     def represent_float(self, data):
         if data != data or (data == 0.0 and data == 1.0):
-            value = u'.nan'
+            value = '.nan'
         elif data == self.inf_value:
-            value = u'.inf'
+            value = '.inf'
         elif data == -self.inf_value:
-            value = u'-.inf'
+            value = '-.inf'
         else:
-            value = unicode(repr(data)).lower()
+            value = str(repr(data)).lower()
             # Note that in some cases `repr(data)` represents a float number
             # without the decimal parts.  For instance:
             #   >>> repr(1e17)
@@ -200,9 +200,9 @@ class SafeRepresenter(BaseRepresenter):
             # Unfortunately, this is not a valid float representation according
             # to the definition of the `!!float` tag.  We fix this by adding
             # '.0' before the 'e' symbol.
-            if u'.' not in value and u'e' in value:
-                value = value.replace(u'e', u'.0e', 1)
-        return self.represent_scalar(u'tag:yaml.org,2002:float', value)
+            if '.' not in value and 'e' in value:
+                value = value.replace('e', '.0e', 1)
+        return self.represent_scalar('tag:yaml.org,2002:float', value)
 
     def represent_list(self, data):
         #pairs = (len(data) > 0 and isinstance(data, list))
@@ -212,7 +212,7 @@ class SafeRepresenter(BaseRepresenter):
         #            pairs = False
         #            break
         #if not pairs:
-            return self.represent_sequence(u'tag:yaml.org,2002:seq', data)
+            return self.represent_sequence('tag:yaml.org,2002:seq', data)
         #value = []
         #for item_key, item_value in data:
         #    value.append(self.represent_mapping(u'tag:yaml.org,2002:map',
@@ -220,21 +220,21 @@ class SafeRepresenter(BaseRepresenter):
         #return SequenceNode(u'tag:yaml.org,2002:pairs', value)
 
     def represent_dict(self, data):
-        return self.represent_mapping(u'tag:yaml.org,2002:map', data)
+        return self.represent_mapping('tag:yaml.org,2002:map', data)
 
     def represent_set(self, data):
         value = {}
         for key in data:
             value[key] = None
-        return self.represent_mapping(u'tag:yaml.org,2002:set', value)
+        return self.represent_mapping('tag:yaml.org,2002:set', value)
 
     def represent_date(self, data):
-        value = unicode(data.isoformat())
-        return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value)
+        value = str(data.isoformat())
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
 
     def represent_datetime(self, data):
-        value = unicode(data.isoformat(' '))
-        return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value)
+        value = str(data.isoformat(' '))
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
 
     def represent_yaml_object(self, tag, data, cls, flow_style=None):
         if hasattr(data, '__getstate__'):
@@ -252,7 +252,7 @@ SafeRepresenter.add_representer(type(None),
 SafeRepresenter.add_representer(str,
         SafeRepresenter.represent_str)
 
-SafeRepresenter.add_representer(unicode,
+SafeRepresenter.add_representer(str,
         SafeRepresenter.represent_unicode)
 
 SafeRepresenter.add_representer(bool,
@@ -261,7 +261,7 @@ SafeRepresenter.add_representer(bool,
 SafeRepresenter.add_representer(int,
         SafeRepresenter.represent_int)
 
-SafeRepresenter.add_representer(long,
+SafeRepresenter.add_representer(int,
         SafeRepresenter.represent_long)
 
 SafeRepresenter.add_representer(float,
@@ -294,15 +294,15 @@ class Representer(SafeRepresenter):
         tag = None
         style = None
         try:
-            data = unicode(data, 'ascii')
-            tag = u'tag:yaml.org,2002:str'
+            data = str(data, 'ascii')
+            tag = 'tag:yaml.org,2002:str'
         except UnicodeDecodeError:
             try:
-                data = unicode(data, 'utf-8')
-                tag = u'tag:yaml.org,2002:python/str'
+                data = str(data, 'utf-8')
+                tag = 'tag:yaml.org,2002:python/str'
             except UnicodeDecodeError:
                 data = data.encode('base64')
-                tag = u'tag:yaml.org,2002:binary'
+                tag = 'tag:yaml.org,2002:binary'
                 style = '|'
         return self.represent_scalar(tag, data, style=style)
 
@@ -310,38 +310,38 @@ class Representer(SafeRepresenter):
         tag = None
         try:
             data.encode('ascii')
-            tag = u'tag:yaml.org,2002:python/unicode'
+            tag = 'tag:yaml.org,2002:python/unicode'
         except UnicodeEncodeError:
-            tag = u'tag:yaml.org,2002:str'
+            tag = 'tag:yaml.org,2002:str'
         return self.represent_scalar(tag, data)
 
     def represent_long(self, data):
-        tag = u'tag:yaml.org,2002:int'
+        tag = 'tag:yaml.org,2002:int'
         if int(data) is not data:
-            tag = u'tag:yaml.org,2002:python/long'
-        return self.represent_scalar(tag, unicode(data))
+            tag = 'tag:yaml.org,2002:python/long'
+        return self.represent_scalar(tag, str(data))
 
     def represent_complex(self, data):
         if data.imag == 0.0:
-            data = u'%r' % data.real
+            data = '%r' % data.real
         elif data.real == 0.0:
-            data = u'%rj' % data.imag
+            data = '%rj' % data.imag
         elif data.imag > 0:
-            data = u'%r+%rj' % (data.real, data.imag)
+            data = '{!r}+{!r}j'.format(data.real, data.imag)
         else:
-            data = u'%r%rj' % (data.real, data.imag)
-        return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data)
+            data = '{!r}{!r}j'.format(data.real, data.imag)
+        return self.represent_scalar('tag:yaml.org,2002:python/complex', data)
 
     def represent_tuple(self, data):
-        return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data)
+        return self.represent_sequence('tag:yaml.org,2002:python/tuple', data)
 
     def represent_name(self, data):
-        name = u'%s.%s' % (data.__module__, data.__name__)
-        return self.represent_scalar(u'tag:yaml.org,2002:python/name:'+name, u'')
+        name = '{}.{}'.format(data.__module__, data.__name__)
+        return self.represent_scalar('tag:yaml.org,2002:python/name:'+name, '')
 
     def represent_module(self, data):
         return self.represent_scalar(
-                u'tag:yaml.org,2002:python/module:'+data.__name__, u'')
+                'tag:yaml.org,2002:python/module:'+data.__name__, '')
 
     def represent_instance(self, data):
         # For instances of classic classes, we use __getinitargs__ and
@@ -362,7 +362,7 @@ class Representer(SafeRepresenter):
         # !!python/object/new node.
 
         cls = data.__class__
-        class_name = u'%s.%s' % (cls.__module__, cls.__name__)
+        class_name = '{}.{}'.format(cls.__module__, cls.__name__)
         args = None
         state = None
         if hasattr(data, '__getinitargs__'):
@@ -373,16 +373,16 @@ class Representer(SafeRepresenter):
             state = data.__dict__
         if args is None and isinstance(state, dict):
             return self.represent_mapping(
-                    u'tag:yaml.org,2002:python/object:'+class_name, state)
+                    'tag:yaml.org,2002:python/object:'+class_name, state)
         if isinstance(state, dict) and not state:
             return self.represent_sequence(
-                    u'tag:yaml.org,2002:python/object/new:'+class_name, args)
+                    'tag:yaml.org,2002:python/object/new:'+class_name, args)
         value = {}
         if args:
             value['args'] = args
         value['state'] = state
         return self.represent_mapping(
-                u'tag:yaml.org,2002:python/object/new:'+class_name, value)
+                'tag:yaml.org,2002:python/object/new:'+class_name, value)
 
     def represent_object(self, data):
         # We use __reduce__ API to save the data. data.__reduce__ returns
@@ -402,8 +402,8 @@ class Representer(SafeRepresenter):
         # !!python/object/apply node.
 
         cls = type(data)
-        if cls in copy_reg.dispatch_table:
-            reduce = copy_reg.dispatch_table[cls](data)
+        if cls in six.moves.copyreg.dispatch_table:
+            reduce = six.moves.copyreg.dispatch_table[cls](data)
         elif hasattr(data, '__reduce_ex__'):
             reduce = data.__reduce_ex__(2)
         elif hasattr(data, '__reduce__'):
@@ -422,16 +422,16 @@ class Representer(SafeRepresenter):
         if function.__name__ == '__newobj__':
             function = args[0]
             args = args[1:]
-            tag = u'tag:yaml.org,2002:python/object/new:'
+            tag = 'tag:yaml.org,2002:python/object/new:'
             newobj = True
         else:
-            tag = u'tag:yaml.org,2002:python/object/apply:'
+            tag = 'tag:yaml.org,2002:python/object/apply:'
             newobj = False
-        function_name = u'%s.%s' % (function.__module__, function.__name__)
+        function_name = '{}.{}'.format(function.__module__, function.__name__)
         if not args and not listitems and not dictitems \
                 and isinstance(state, dict) and newobj:
             return self.represent_mapping(
-                    u'tag:yaml.org,2002:python/object:'+function_name, state)
+                    'tag:yaml.org,2002:python/object:'+function_name, state)
         if not listitems and not dictitems  \
                 and isinstance(state, dict) and not state:
             return self.represent_sequence(tag+function_name, args)
@@ -449,10 +449,10 @@ class Representer(SafeRepresenter):
 Representer.add_representer(str,
         Representer.represent_str)
 
-Representer.add_representer(unicode,
+Representer.add_representer(str,
         Representer.represent_unicode)
 
-Representer.add_representer(long,
+Representer.add_representer(int,
         Representer.represent_long)
 
 Representer.add_representer(complex,
@@ -464,7 +464,7 @@ Representer.add_representer(tuple,
 Representer.add_representer(type,
         Representer.represent_name)
 
-Representer.add_representer(types.ClassType,
+Representer.add_representer(type,
         Representer.represent_name)
 
 Representer.add_representer(types.FunctionType,
diff --git a/python/pyyaml/lib/yaml/resolver.py b/python/pyyaml/lib/yaml/resolver.py
index 6b5ab87596..72b33986b4 100644
--- a/python/pyyaml/lib/yaml/resolver.py
+++ b/python/pyyaml/lib/yaml/resolver.py
@@ -1,4 +1,3 @@
-
 __all__ = ['BaseResolver', 'Resolver']
 
 from error import *
@@ -11,9 +10,9 @@ class ResolverError(YAMLError):
 
 class BaseResolver(object):
 
-    DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
-    DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq'
-    DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map'
+    DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str'
+    DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq'
+    DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map'
 
     yaml_implicit_resolvers = {}
     yaml_path_resolvers = {}
@@ -139,8 +138,8 @@ class BaseResolver(object):
 
     def resolve(self, kind, value, implicit):
         if kind is ScalarNode and implicit[0]:
-            if value == u'':
-                resolvers = self.yaml_implicit_resolvers.get(u'', [])
+            if value == '':
+                resolvers = self.yaml_implicit_resolvers.get('', [])
             else:
                 resolvers = self.yaml_implicit_resolvers.get(value[0], [])
             resolvers += self.yaml_implicit_resolvers.get(None, [])
@@ -165,60 +164,60 @@ class Resolver(BaseResolver):
     pass
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:bool',
-        re.compile(ur'''^(?:yes|Yes|YES|no|No|NO
+        'tag:yaml.org,2002:bool',
+        re.compile(r'''^(?:yes|Yes|YES|no|No|NO
                     |true|True|TRUE|false|False|FALSE
                     |on|On|ON|off|Off|OFF)$''', re.X),
-        list(u'yYnNtTfFoO'))
+        list('yYnNtTfFoO'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:float',
-        re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
+        'tag:yaml.org,2002:float',
+        re.compile(urr'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
                     |\.[0-9_]+(?:[eE][-+][0-9]+)?
                     |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*
                     |[-+]?\.(?:inf|Inf|INF)
                     |\.(?:nan|NaN|NAN))$''', re.X),
-        list(u'-+0123456789.'))
+        list('-+0123456789.'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:int',
-        re.compile(ur'''^(?:[-+]?0b[0-1_]+
+        'tag:yaml.org,2002:int',
+        re.compile(r'''^(?:[-+]?0b[0-1_]+
                     |[-+]?0[0-7_]+
                     |[-+]?(?:0|[1-9][0-9_]*)
                     |[-+]?0x[0-9a-fA-F_]+
                     |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),
-        list(u'-+0123456789'))
+        list('-+0123456789'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:merge',
-        re.compile(ur'^(?:<<)$'),
-        [u'<'])
+        'tag:yaml.org,2002:merge',
+        re.compile(r'^(?:<<)$'),
+        ['<'])
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:null',
-        re.compile(ur'''^(?: ~
+        'tag:yaml.org,2002:null',
+        re.compile(r'''^(?: ~
                     |null|Null|NULL
                     | )$''', re.X),
-        [u'~', u'n', u'N', u''])
+        ['~', 'n', 'N', ''])
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:timestamp',
-        re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
+        'tag:yaml.org,2002:timestamp',
+        re.compile(r'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
                     |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
                      (?:[Tt]|[ \t]+)[0-9][0-9]?
-                     :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)?
+                     :[0-9][0-9] :[0-9][0-9] (?:\\.[0-9]*)?
                      (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
-        list(u'0123456789'))
+        list('0123456789'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:value',
-        re.compile(ur'^(?:=)$'),
-        [u'='])
+        'tag:yaml.org,2002:value',
+        re.compile(r'^(?:=)$'),
+        ['='])
 
 # The following resolver is only for documentation purposes. It cannot work
 # because plain scalars cannot start with '!', '&', or '*'.
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:yaml',
-        re.compile(ur'^(?:!|&|\*)$'),
-        list(u'!&*'))
+        'tag:yaml.org,2002:yaml',
+        re.compile(urr'^(?:!|&|\*)$'),
+        list('!&*'))
 
diff --git a/python/pyyaml/lib/yaml/scanner.py b/python/pyyaml/lib/yaml/scanner.py
index 5228fad65c..e0ed422119 100644
--- a/python/pyyaml/lib/yaml/scanner.py
+++ b/python/pyyaml/lib/yaml/scanner.py
@@ -1,4 +1,3 @@
-
 # Scanner produces tokens of the following types:
 # STREAM-START
 # STREAM-END
@@ -24,10 +23,11 @@
 # Read comments in the Scanner code for more details.
 #
 
+unichr = chr
 __all__ = ['Scanner', 'ScannerError']
 
-from error import MarkedYAMLError
-from tokens import *
+from .error import MarkedYAMLError
+from .tokens import *
 
 class ScannerError(MarkedYAMLError):
     pass
@@ -166,19 +166,19 @@ class Scanner(object):
         ch = self.peek()
 
         # Is it the end of stream?
-        if ch == u'\0':
+        if ch == '\0':
             return self.fetch_stream_end()
 
         # Is it a directive?
-        if ch == u'%' and self.check_directive():
+        if ch == '%' and self.check_directive():
             return self.fetch_directive()
 
         # Is it the document start?
-        if ch == u'-' and self.check_document_start():
+        if ch == '-' and self.check_document_start():
             return self.fetch_document_start()
 
         # Is it the document end?
-        if ch == u'.' and self.check_document_end():
+        if ch == '.' and self.check_document_end():
             return self.fetch_document_end()
 
         # TODO: support for BOM within a stream.
@@ -188,63 +188,63 @@ class Scanner(object):
         # Note: the order of the following checks is NOT significant.
 
         # Is it the flow sequence start indicator?
-        if ch == u'[':
+        if ch == '[':
             return self.fetch_flow_sequence_start()
 
         # Is it the flow mapping start indicator?
-        if ch == u'{':
+        if ch == '{':
             return self.fetch_flow_mapping_start()
 
         # Is it the flow sequence end indicator?
-        if ch == u']':
+        if ch == ']':
             return self.fetch_flow_sequence_end()
 
         # Is it the flow mapping end indicator?
-        if ch == u'}':
+        if ch == '}':
             return self.fetch_flow_mapping_end()
 
         # Is it the flow entry indicator?
-        if ch == u',':
+        if ch == ',':
             return self.fetch_flow_entry()
 
         # Is it the block entry indicator?
-        if ch == u'-' and self.check_block_entry():
+        if ch == '-' and self.check_block_entry():
             return self.fetch_block_entry()
 
         # Is it the key indicator?
-        if ch == u'?' and self.check_key():
+        if ch == '?' and self.check_key():
             return self.fetch_key()
 
         # Is it the value indicator?
-        if ch == u':' and self.check_value():
+        if ch == ':' and self.check_value():
             return self.fetch_value()
 
         # Is it an alias?
-        if ch == u'*':
+        if ch == '*':
             return self.fetch_alias()
 
         # Is it an anchor?
-        if ch == u'&':
+        if ch == '&':
             return self.fetch_anchor()
 
         # Is it a tag?
-        if ch == u'!':
+        if ch == '!':
             return self.fetch_tag()
 
         # Is it a literal scalar?
-        if ch == u'|' and not self.flow_level:
+        if ch == '|' and not self.flow_level:
             return self.fetch_literal()
 
         # Is it a folded scalar?
-        if ch == u'>' and not self.flow_level:
+        if ch == '>' and not self.flow_level:
             return self.fetch_folded()
 
         # Is it a single quoted scalar?
-        if ch == u'\'':
+        if ch == '\'':
             return self.fetch_single()
 
         # Is it a double quoted scalar?
-        if ch == u'\"':
+        if ch == '\"':
             return self.fetch_double()
 
         # It must be a plain scalar then.
@@ -692,22 +692,22 @@ class Scanner(object):
 
         # DOCUMENT-START:   ^ '---' (' '|'\n')
         if self.column == 0:
-            if self.prefix(3) == u'---'  \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if self.prefix(3) == '---'  \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 return True
 
     def check_document_end(self):
 
         # DOCUMENT-END:     ^ '...' (' '|'\n')
         if self.column == 0:
-            if self.prefix(3) == u'...'  \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if self.prefix(3) == '...'  \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 return True
 
     def check_block_entry(self):
 
         # BLOCK-ENTRY:      '-' (' '|'\n')
-        return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+        return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029'
 
     def check_key(self):
 
@@ -717,7 +717,7 @@ class Scanner(object):
 
         # KEY(block context):   '?' (' '|'\n')
         else:
-            return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+            return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029'
 
     def check_value(self):
 
@@ -727,7 +727,7 @@ class Scanner(object):
 
         # VALUE(block context): ':' (' '|'\n')
         else:
-            return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+            return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029'
 
     def check_plain(self):
 
@@ -744,9 +744,9 @@ class Scanner(object):
         # '-' character) because we want the flow context to be space
         # independent.
         ch = self.peek()
-        return ch not in u'\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`'  \
-                or (self.peek(1) not in u'\0 \t\r\n\x85\u2028\u2029'
-                        and (ch == u'-' or (not self.flow_level and ch in u'?:')))
+        return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`'  \
+                or (self.peek(1) not in '\0 \t\r\n\x85\u2028\u2029'
+                        and (ch == '-' or (not self.flow_level and ch in '?:')))
 
     # Scanners.
 
@@ -770,14 +770,14 @@ class Scanner(object):
         # `unwind_indent` before issuing BLOCK-END.
         # Scanners for block, flow, and plain scalars need to be modified.
 
-        if self.index == 0 and self.peek() == u'\uFEFF':
+        if self.index == 0 and self.peek() == '\uFEFF':
             self.forward()
         found = False
         while not found:
-            while self.peek() == u' ':
+            while self.peek() == ' ':
                 self.forward()
-            if self.peek() == u'#':
-                while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+            if self.peek() == '#':
+                while self.peek() not in '\0\r\n\x85\u2028\u2029':
                     self.forward()
             if self.scan_line_break():
                 if not self.flow_level:
@@ -791,15 +791,15 @@ class Scanner(object):
         self.forward()
         name = self.scan_directive_name(start_mark)
         value = None
-        if name == u'YAML':
+        if name == 'YAML':
             value = self.scan_yaml_directive_value(start_mark)
             end_mark = self.get_mark()
-        elif name == u'TAG':
+        elif name == 'TAG':
             value = self.scan_tag_directive_value(start_mark)
             end_mark = self.get_mark()
         else:
             end_mark = self.get_mark()
-            while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+            while self.peek() not in '\0\r\n\x85\u2028\u2029':
                 self.forward()
         self.scan_directive_ignored_line(start_mark)
         return DirectiveToken(name, value, start_mark, end_mark)
@@ -808,8 +808,8 @@ class Scanner(object):
         # See the specification for details.
         length = 0
         ch = self.peek(length)
-        while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'    \
-                or ch in u'-_':
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'    \
+                or ch in '-_':
             length += 1
             ch = self.peek(length)
         if not length:
@@ -819,7 +819,7 @@ class Scanner(object):
         value = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected alphabetic or numeric character, but found %r"
                     % ch.encode('utf-8'), self.get_mark())
@@ -827,7 +827,7 @@ class Scanner(object):
 
     def scan_yaml_directive_value(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
         major = self.scan_yaml_directive_number(start_mark)
         if self.peek() != '.':
@@ -837,7 +837,7 @@ class Scanner(object):
                     self.get_mark())
         self.forward()
         minor = self.scan_yaml_directive_number(start_mark)
-        if self.peek() not in u'\0 \r\n\x85\u2028\u2029':
+        if self.peek() not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected a digit or ' ', but found %r"
                     % self.peek().encode('utf-8'),
@@ -847,12 +847,12 @@ class Scanner(object):
     def scan_yaml_directive_number(self, start_mark):
         # See the specification for details.
         ch = self.peek()
-        if not (u'0' <= ch <= u'9'):
+        if not ('0' <= ch <= '9'):
             raise ScannerError("while scanning a directive", start_mark,
                     "expected a digit, but found %r" % ch.encode('utf-8'),
                     self.get_mark())
         length = 0
-        while u'0' <= self.peek(length) <= u'9':
+        while '0' <= self.peek(length) <= '9':
             length += 1
         value = int(self.prefix(length))
         self.forward(length)
@@ -860,10 +860,10 @@ class Scanner(object):
 
     def scan_tag_directive_value(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
         handle = self.scan_tag_directive_handle(start_mark)
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
         prefix = self.scan_tag_directive_prefix(start_mark)
         return (handle, prefix)
@@ -872,7 +872,7 @@ class Scanner(object):
         # See the specification for details.
         value = self.scan_tag_handle('directive', start_mark)
         ch = self.peek()
-        if ch != u' ':
+        if ch != ' ':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected ' ', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
@@ -882,7 +882,7 @@ class Scanner(object):
         # See the specification for details.
         value = self.scan_tag_uri('directive', start_mark)
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected ' ', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
@@ -890,13 +890,13 @@ class Scanner(object):
 
     def scan_directive_ignored_line(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
-        if self.peek() == u'#':
-            while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+        if self.peek() == '#':
+            while self.peek() not in '\0\r\n\x85\u2028\u2029':
                 self.forward()
         ch = self.peek()
-        if ch not in u'\0\r\n\x85\u2028\u2029':
+        if ch not in '\0\r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected a comment or a line break, but found %r"
                         % ch.encode('utf-8'), self.get_mark())
@@ -913,15 +913,15 @@ class Scanner(object):
         # Therefore we restrict aliases to numbers and ASCII letters.
         start_mark = self.get_mark()
         indicator = self.peek()
-        if indicator == u'*':
+        if indicator == '*':
             name = 'alias'
         else:
             name = 'anchor'
         self.forward()
         length = 0
         ch = self.peek(length)
-        while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'    \
-                or ch in u'-_':
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'    \
+                or ch in '-_':
             length += 1
             ch = self.peek(length)
         if not length:
@@ -931,7 +931,7 @@ class Scanner(object):
         value = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch not in u'\0 \t\r\n\x85\u2028\u2029?:,]}%@`':
+        if ch not in '\0 \t\r\n\x85\u2028\u2029?:,]}%@`':
             raise ScannerError("while scanning an %s" % name, start_mark,
                     "expected alphabetic or numeric character, but found %r"
                     % ch.encode('utf-8'), self.get_mark())
@@ -942,37 +942,37 @@ class Scanner(object):
         # See the specification for details.
         start_mark = self.get_mark()
         ch = self.peek(1)
-        if ch == u'<':
+        if ch == '<':
             handle = None
             self.forward(2)
             suffix = self.scan_tag_uri('tag', start_mark)
-            if self.peek() != u'>':
+            if self.peek() != '>':
                 raise ScannerError("while parsing a tag", start_mark,
                         "expected '>', but found %r" % self.peek().encode('utf-8'),
                         self.get_mark())
             self.forward()
-        elif ch in u'\0 \t\r\n\x85\u2028\u2029':
+        elif ch in '\0 \t\r\n\x85\u2028\u2029':
             handle = None
-            suffix = u'!'
+            suffix = '!'
             self.forward()
         else:
             length = 1
             use_handle = False
-            while ch not in u'\0 \r\n\x85\u2028\u2029':
-                if ch == u'!':
+            while ch not in '\0 \r\n\x85\u2028\u2029':
+                if ch == '!':
                     use_handle = True
                     break
                 length += 1
                 ch = self.peek(length)
-            handle = u'!'
+            handle = '!'
             if use_handle:
                 handle = self.scan_tag_handle('tag', start_mark)
             else:
-                handle = u'!'
+                handle = '!'
                 self.forward()
             suffix = self.scan_tag_uri('tag', start_mark)
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a tag", start_mark,
                     "expected ' ', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
@@ -1006,29 +1006,29 @@ class Scanner(object):
         else:
             indent = min_indent+increment-1
             breaks, end_mark = self.scan_block_scalar_breaks(indent)
-        line_break = u''
+        line_break = ''
 
         # Scan the inner part of the block scalar.
-        while self.column == indent and self.peek() != u'\0':
+        while self.column == indent and self.peek() != '\0':
             chunks.extend(breaks)
-            leading_non_space = self.peek() not in u' \t'
+            leading_non_space = self.peek() not in ' \t'
             length = 0
-            while self.peek(length) not in u'\0\r\n\x85\u2028\u2029':
+            while self.peek(length) not in '\0\r\n\x85\u2028\u2029':
                 length += 1
             chunks.append(self.prefix(length))
             self.forward(length)
             line_break = self.scan_line_break()
             breaks, end_mark = self.scan_block_scalar_breaks(indent)
-            if self.column == indent and self.peek() != u'\0':
+            if self.column == indent and self.peek() != '\0':
 
                 # Unfortunately, folding rules are ambiguous.
                 #
                 # This is the folding according to the specification:
                 
-                if folded and line_break == u'\n'   \
-                        and leading_non_space and self.peek() not in u' \t':
+                if folded and line_break == '\n'   \
+                        and leading_non_space and self.peek() not in ' \t':
                     if not breaks:
-                        chunks.append(u' ')
+                        chunks.append(' ')
                 else:
                     chunks.append(line_break)
                 
@@ -1053,7 +1053,7 @@ class Scanner(object):
             chunks.extend(breaks)
 
         # We are done.
-        return ScalarToken(u''.join(chunks), False, start_mark, end_mark,
+        return ScalarToken(''.join(chunks), False, start_mark, end_mark,
                 style)
 
     def scan_block_scalar_indicators(self, start_mark):
@@ -1061,21 +1061,21 @@ class Scanner(object):
         chomping = None
         increment = None
         ch = self.peek()
-        if ch in u'+-':
+        if ch in '+-':
             if ch == '+':
                 chomping = True
             else:
                 chomping = False
             self.forward()
             ch = self.peek()
-            if ch in u'0123456789':
+            if ch in '0123456789':
                 increment = int(ch)
                 if increment == 0:
                     raise ScannerError("while scanning a block scalar", start_mark,
                             "expected indentation indicator in the range 1-9, but found 0",
                             self.get_mark())
                 self.forward()
-        elif ch in u'0123456789':
+        elif ch in '0123456789':
             increment = int(ch)
             if increment == 0:
                 raise ScannerError("while scanning a block scalar", start_mark,
@@ -1083,14 +1083,14 @@ class Scanner(object):
                         self.get_mark())
             self.forward()
             ch = self.peek()
-            if ch in u'+-':
+            if ch in '+-':
                 if ch == '+':
                     chomping = True
                 else:
                     chomping = False
                 self.forward()
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a block scalar", start_mark,
                     "expected chomping or indentation indicators, but found %r"
                         % ch.encode('utf-8'), self.get_mark())
@@ -1098,13 +1098,13 @@ class Scanner(object):
 
     def scan_block_scalar_ignored_line(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
-        if self.peek() == u'#':
-            while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+        if self.peek() == '#':
+            while self.peek() not in '\0\r\n\x85\u2028\u2029':
                 self.forward()
         ch = self.peek()
-        if ch not in u'\0\r\n\x85\u2028\u2029':
+        if ch not in '\0\r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a block scalar", start_mark,
                     "expected a comment or a line break, but found %r"
                         % ch.encode('utf-8'), self.get_mark())
@@ -1115,8 +1115,8 @@ class Scanner(object):
         chunks = []
         max_indent = 0
         end_mark = self.get_mark()
-        while self.peek() in u' \r\n\x85\u2028\u2029':
-            if self.peek() != u' ':
+        while self.peek() in ' \r\n\x85\u2028\u2029':
+            if self.peek() != ' ':
                 chunks.append(self.scan_line_break())
                 end_mark = self.get_mark()
             else:
@@ -1129,12 +1129,12 @@ class Scanner(object):
         # See the specification for details.
         chunks = []
         end_mark = self.get_mark()
-        while self.column < indent and self.peek() == u' ':
+        while self.column < indent and self.peek() == ' ':
             self.forward()
-        while self.peek() in u'\r\n\x85\u2028\u2029':
+        while self.peek() in '\r\n\x85\u2028\u2029':
             chunks.append(self.scan_line_break())
             end_mark = self.get_mark()
-            while self.column < indent and self.peek() == u' ':
+            while self.column < indent and self.peek() == ' ':
                 self.forward()
         return chunks, end_mark
 
@@ -1159,33 +1159,33 @@ class Scanner(object):
             chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
         self.forward()
         end_mark = self.get_mark()
-        return ScalarToken(u''.join(chunks), False, start_mark, end_mark,
+        return ScalarToken(''.join(chunks), False, start_mark, end_mark,
                 style)
 
     ESCAPE_REPLACEMENTS = {
-        u'0':   u'\0',
-        u'a':   u'\x07',
-        u'b':   u'\x08',
-        u't':   u'\x09',
-        u'\t':  u'\x09',
-        u'n':   u'\x0A',
-        u'v':   u'\x0B',
-        u'f':   u'\x0C',
-        u'r':   u'\x0D',
-        u'e':   u'\x1B',
-        u' ':   u'\x20',
-        u'\"':  u'\"',
-        u'\\':  u'\\',
-        u'N':   u'\x85',
-        u'_':   u'\xA0',
-        u'L':   u'\u2028',
-        u'P':   u'\u2029',
+        '0':   '\0',
+        'a':   '\x07',
+        'b':   '\x08',
+        't':   '\x09',
+        '\t':  '\x09',
+        'n':   '\x0A',
+        'v':   '\x0B',
+        'f':   '\x0C',
+        'r':   '\x0D',
+        'e':   '\x1B',
+        ' ':   '\x20',
+        '\"':  '\"',
+        '\\':  '\\',
+        'N':   '\x85',
+        '_':   '\xA0',
+        'L':   '\u2028',
+        'P':   '\u2029',
     }
 
     ESCAPE_CODES = {
-        u'x':   2,
-        u'u':   4,
-        u'U':   8,
+        'x':   2,
+        'u':   4,
+        'U':   8,
     }
 
     def scan_flow_scalar_non_spaces(self, double, start_mark):
@@ -1193,19 +1193,19 @@ class Scanner(object):
         chunks = []
         while True:
             length = 0
-            while self.peek(length) not in u'\'\"\\\0 \t\r\n\x85\u2028\u2029':
+            while self.peek(length) not in '\'\"\\\0 \t\r\n\x85\u2028\u2029':
                 length += 1
             if length:
                 chunks.append(self.prefix(length))
                 self.forward(length)
             ch = self.peek()
-            if not double and ch == u'\'' and self.peek(1) == u'\'':
-                chunks.append(u'\'')
+            if not double and ch == '\'' and self.peek(1) == '\'':
+                chunks.append('\'')
                 self.forward(2)
-            elif (double and ch == u'\'') or (not double and ch in u'\"\\'):
+            elif (double and ch == '\'') or (not double and ch in '\"\\'):
                 chunks.append(ch)
                 self.forward()
-            elif double and ch == u'\\':
+            elif double and ch == '\\':
                 self.forward()
                 ch = self.peek()
                 if ch in self.ESCAPE_REPLACEMENTS:
@@ -1215,14 +1215,14 @@ class Scanner(object):
                     length = self.ESCAPE_CODES[ch]
                     self.forward()
                     for k in range(length):
-                        if self.peek(k) not in u'0123456789ABCDEFabcdef':
+                        if self.peek(k) not in '0123456789ABCDEFabcdef':
                             raise ScannerError("while scanning a double-quoted scalar", start_mark,
                                     "expected escape sequence of %d hexdecimal numbers, but found %r" %
                                         (length, self.peek(k).encode('utf-8')), self.get_mark())
                     code = int(self.prefix(length), 16)
                     chunks.append(unichr(code))
                     self.forward(length)
-                elif ch in u'\r\n\x85\u2028\u2029':
+                elif ch in '\r\n\x85\u2028\u2029':
                     self.scan_line_break()
                     chunks.extend(self.scan_flow_scalar_breaks(double, start_mark))
                 else:
@@ -1235,21 +1235,21 @@ class Scanner(object):
         # See the specification for details.
         chunks = []
         length = 0
-        while self.peek(length) in u' \t':
+        while self.peek(length) in ' \t':
             length += 1
         whitespaces = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch == u'\0':
+        if ch == '\0':
             raise ScannerError("while scanning a quoted scalar", start_mark,
                     "found unexpected end of stream", self.get_mark())
-        elif ch in u'\r\n\x85\u2028\u2029':
+        elif ch in '\r\n\x85\u2028\u2029':
             line_break = self.scan_line_break()
             breaks = self.scan_flow_scalar_breaks(double, start_mark)
-            if line_break != u'\n':
+            if line_break != '\n':
                 chunks.append(line_break)
             elif not breaks:
-                chunks.append(u' ')
+                chunks.append(' ')
             chunks.extend(breaks)
         else:
             chunks.append(whitespaces)
@@ -1262,13 +1262,13 @@ class Scanner(object):
             # Instead of checking indentation, we check for document
             # separators.
             prefix = self.prefix(3)
-            if (prefix == u'---' or prefix == u'...')   \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if (prefix == '---' or prefix == '...')   \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 raise ScannerError("while scanning a quoted scalar", start_mark,
                         "found unexpected document separator", self.get_mark())
-            while self.peek() in u' \t':
+            while self.peek() in ' \t':
                 self.forward()
-            if self.peek() in u'\r\n\x85\u2028\u2029':
+            if self.peek() in '\r\n\x85\u2028\u2029':
                 chunks.append(self.scan_line_break())
             else:
                 return chunks
@@ -1290,19 +1290,19 @@ class Scanner(object):
         spaces = []
         while True:
             length = 0
-            if self.peek() == u'#':
+            if self.peek() == '#':
                 break
             while True:
                 ch = self.peek(length)
-                if ch in u'\0 \t\r\n\x85\u2028\u2029'   \
-                        or (not self.flow_level and ch == u':' and
-                                self.peek(length+1) in u'\0 \t\r\n\x85\u2028\u2029') \
-                        or (self.flow_level and ch in u',:?[]{}'):
+                if ch in '\0 \t\r\n\x85\u2028\u2029'   \
+                        or (not self.flow_level and ch == ':' and
+                                self.peek(length+1) in '\0 \t\r\n\x85\u2028\u2029') \
+                        or (self.flow_level and ch in ',:?[]{}'):
                     break
                 length += 1
             # It's not clear what we should do with ':' in the flow context.
-            if (self.flow_level and ch == u':'
-                    and self.peek(length+1) not in u'\0 \t\r\n\x85\u2028\u2029,[]{}'):
+            if (self.flow_level and ch == ':'
+                    and self.peek(length+1) not in '\0 \t\r\n\x85\u2028\u2029,[]{}'):
                 self.forward(length)
                 raise ScannerError("while scanning a plain scalar", start_mark,
                     "found unexpected ':'", self.get_mark(),
@@ -1315,10 +1315,10 @@ class Scanner(object):
             self.forward(length)
             end_mark = self.get_mark()
             spaces = self.scan_plain_spaces(indent, start_mark)
-            if not spaces or self.peek() == u'#' \
+            if not spaces or self.peek() == '#' \
                     or (not self.flow_level and self.column < indent):
                 break
-        return ScalarToken(u''.join(chunks), True, start_mark, end_mark)
+        return ScalarToken(''.join(chunks), True, start_mark, end_mark)
 
     def scan_plain_spaces(self, indent, start_mark):
         # See the specification for details.
@@ -1326,32 +1326,32 @@ class Scanner(object):
         # We just forbid them completely. Do not use tabs in YAML!
         chunks = []
         length = 0
-        while self.peek(length) in u' ':
+        while self.peek(length) in ' ':
             length += 1
         whitespaces = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch in u'\r\n\x85\u2028\u2029':
+        if ch in '\r\n\x85\u2028\u2029':
             line_break = self.scan_line_break()
             self.allow_simple_key = True
             prefix = self.prefix(3)
-            if (prefix == u'---' or prefix == u'...')   \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if (prefix == '---' or prefix == '...')   \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 return
             breaks = []
-            while self.peek() in u' \r\n\x85\u2028\u2029':
+            while self.peek() in ' \r\n\x85\u2028\u2029':
                 if self.peek() == ' ':
                     self.forward()
                 else:
                     breaks.append(self.scan_line_break())
                     prefix = self.prefix(3)
-                    if (prefix == u'---' or prefix == u'...')   \
-                            and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+                    if (prefix == '---' or prefix == '...')   \
+                            and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                         return
-            if line_break != u'\n':
+            if line_break != '\n':
                 chunks.append(line_break)
             elif not breaks:
-                chunks.append(u' ')
+                chunks.append(' ')
             chunks.extend(breaks)
         elif whitespaces:
             chunks.append(whitespaces)
@@ -1362,18 +1362,18 @@ class Scanner(object):
         # For some strange reasons, the specification does not allow '_' in
         # tag handles. I have allowed it anyway.
         ch = self.peek()
-        if ch != u'!':
+        if ch != '!':
             raise ScannerError("while scanning a %s" % name, start_mark,
                     "expected '!', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
         length = 1
         ch = self.peek(length)
-        if ch != u' ':
-            while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'    \
-                    or ch in u'-_':
+        if ch != ' ':
+            while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'    \
+                    or ch in '-_':
                 length += 1
                 ch = self.peek(length)
-            if ch != u'!':
+            if ch != '!':
                 self.forward(length)
                 raise ScannerError("while scanning a %s" % name, start_mark,
                         "expected '!', but found %r" % ch.encode('utf-8'),
@@ -1389,9 +1389,9 @@ class Scanner(object):
         chunks = []
         length = 0
         ch = self.peek(length)
-        while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z'    \
-                or ch in u'-;/?:@&=+$,_.!~*\'()[]%':
-            if ch == u'%':
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'    \
+                or ch in '-;/?:@&=+$,_.!~*\'()[]%':
+            if ch == '%':
                 chunks.append(self.prefix(length))
                 self.forward(length)
                 length = 0
@@ -1407,24 +1407,24 @@ class Scanner(object):
             raise ScannerError("while parsing a %s" % name, start_mark,
                     "expected URI, but found %r" % ch.encode('utf-8'),
                     self.get_mark())
-        return u''.join(chunks)
+        return ''.join(chunks)
 
     def scan_uri_escapes(self, name, start_mark):
         # See the specification for details.
         bytes = []
         mark = self.get_mark()
-        while self.peek() == u'%':
+        while self.peek() == '%':
             self.forward()
             for k in range(2):
-                if self.peek(k) not in u'0123456789ABCDEFabcdef':
+                if self.peek(k) not in '0123456789ABCDEFabcdef':
                     raise ScannerError("while scanning a %s" % name, start_mark,
                             "expected URI escape sequence of 2 hexdecimal numbers, but found %r" %
                                 (self.peek(k).encode('utf-8')), self.get_mark())
             bytes.append(chr(int(self.prefix(2), 16)))
             self.forward(2)
         try:
-            value = unicode(''.join(bytes), 'utf-8')
-        except UnicodeDecodeError, exc:
+            value = str(''.join(bytes), 'utf-8')
+        except UnicodeDecodeError as exc:
             raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark)
         return value
 
@@ -1438,16 +1438,16 @@ class Scanner(object):
         #   '\u2029     :   '\u2029'
         #   default     :   ''
         ch = self.peek()
-        if ch in u'\r\n\x85':
-            if self.prefix(2) == u'\r\n':
+        if ch in '\r\n\x85':
+            if self.prefix(2) == '\r\n':
                 self.forward(2)
             else:
                 self.forward()
-            return u'\n'
-        elif ch in u'\u2028\u2029':
+            return '\n'
+        elif ch in '\u2028\u2029':
             self.forward()
             return ch
-        return u''
+        return ''
 
 #try:
 #    import psyco
diff --git a/python/pyyaml/lib/yaml/serializer.py b/python/pyyaml/lib/yaml/serializer.py
index 0bf1e96dc1..89eb64e5eb 100644
--- a/python/pyyaml/lib/yaml/serializer.py
+++ b/python/pyyaml/lib/yaml/serializer.py
@@ -1,16 +1,15 @@
-
 __all__ = ['Serializer', 'SerializerError']
 
-from error import YAMLError
-from events import *
-from nodes import *
+from .error import YAMLError
+from .events import *
+from .nodes import *
 
 class SerializerError(YAMLError):
     pass
 
-class Serializer(object):
+class Serializer:
 
-    ANCHOR_TEMPLATE = u'id%03d'
+    ANCHOR_TEMPLATE = 'id%03d'
 
     def __init__(self, encoding=None,
             explicit_start=None, explicit_end=None, version=None, tags=None):
diff --git a/python/pyyaml/lib/yaml/tokens.py b/python/pyyaml/lib/yaml/tokens.py
index 4d0b48a394..93f5700e28 100644
--- a/python/pyyaml/lib/yaml/tokens.py
+++ b/python/pyyaml/lib/yaml/tokens.py
@@ -1,5 +1,4 @@
-
-class Token(object):
+class Token:
     def __init__(self, start_mark, end_mark):
         self.start_mark = start_mark
         self.end_mark = end_mark
@@ -7,9 +6,9 @@ class Token(object):
         attributes = [key for key in self.__dict__
                 if not key.endswith('_mark')]
         attributes.sort()
-        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
+        arguments = ', '.join(['{}={!r}'.format(key, getattr(self, key))
                 for key in attributes])
-        return '%s(%s)' % (self.__class__.__name__, arguments)
+        return '{}({})'.format(self.__class__.__name__, arguments)
 
 #class BOMToken(Token):
 #    id = ''
diff --git a/python/pyyaml/lib3/yaml/__init__.py b/python/pyyaml/lib3/yaml/__init__.py
index a5e20f94d2..b3e4c7ce06 100644
--- a/python/pyyaml/lib3/yaml/__init__.py
+++ b/python/pyyaml/lib3/yaml/__init__.py
@@ -1,4 +1,3 @@
-
 from .error import *
 
 from .tokens import *
@@ -276,7 +275,7 @@ class YAMLObjectMetaclass(type):
     The metaclass for YAMLObject.
     """
     def __init__(cls, name, bases, kwds):
-        super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds)
+        super().__init__(name, bases, kwds)
         if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
             cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
             cls.yaml_dumper.add_representer(cls, cls.to_yaml)
diff --git a/python/pyyaml/lib3/yaml/composer.py b/python/pyyaml/lib3/yaml/composer.py
index d5c6a7acd9..5de30b4758 100644
--- a/python/pyyaml/lib3/yaml/composer.py
+++ b/python/pyyaml/lib3/yaml/composer.py
@@ -1,4 +1,3 @@
-
 __all__ = ['Composer', 'ComposerError']
 
 from .error import MarkedYAMLError
diff --git a/python/pyyaml/lib3/yaml/constructor.py b/python/pyyaml/lib3/yaml/constructor.py
index 981543aebb..7d6482df38 100644
--- a/python/pyyaml/lib3/yaml/constructor.py
+++ b/python/pyyaml/lib3/yaml/constructor.py
@@ -1,4 +1,3 @@
-
 __all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
     'ConstructorError']
 
@@ -123,7 +122,7 @@ class BaseConstructor:
         mapping = {}
         for key_node, value_node in node.value:
             key = self.construct_object(key_node, deep=deep)
-            if not isinstance(key, collections.Hashable):
+            if not isinstance(key, collections.abc.Hashable):
                 raise ConstructorError("while constructing a mapping", node.start_mark,
                         "found unhashable key", key_node.start_mark)
             value = self.construct_object(value_node, deep=deep)
@@ -505,7 +504,7 @@ class Constructor(SafeConstructor):
             __import__(name)
         except ImportError as exc:
             raise ConstructorError("while constructing a Python module", mark,
-                    "cannot find module %r (%s)" % (name, exc), mark)
+                    "cannot find module {!r} ({})".format(name, exc), mark)
         return sys.modules[name]
 
     def find_python_name(self, name, mark):
@@ -521,7 +520,7 @@ class Constructor(SafeConstructor):
             __import__(module_name)
         except ImportError as exc:
             raise ConstructorError("while constructing a Python object", mark,
-                    "cannot find module %r (%s)" % (module_name, exc), mark)
+                    "cannot find module {!r} ({})".format(module_name, exc), mark)
         module = sys.modules[module_name]
         if not hasattr(module, object_name):
             raise ConstructorError("while constructing a Python object", mark,
diff --git a/python/pyyaml/lib3/yaml/cyaml.py b/python/pyyaml/lib3/yaml/cyaml.py
index d5cb87e994..0baa920d40 100644
--- a/python/pyyaml/lib3/yaml/cyaml.py
+++ b/python/pyyaml/lib3/yaml/cyaml.py
@@ -1,4 +1,3 @@
-
 __all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader',
         'CBaseDumper', 'CSafeDumper', 'CDumper']
 
diff --git a/python/pyyaml/lib3/yaml/dumper.py b/python/pyyaml/lib3/yaml/dumper.py
index 0b69128771..dfd8c7cf36 100644
--- a/python/pyyaml/lib3/yaml/dumper.py
+++ b/python/pyyaml/lib3/yaml/dumper.py
@@ -1,4 +1,3 @@
-
 __all__ = ['BaseDumper', 'SafeDumper', 'Dumper']
 
 from .emitter import *
diff --git a/python/pyyaml/lib3/yaml/emitter.py b/python/pyyaml/lib3/yaml/emitter.py
index 34cb145a5f..c0bfcf1f85 100644
--- a/python/pyyaml/lib3/yaml/emitter.py
+++ b/python/pyyaml/lib3/yaml/emitter.py
@@ -1,4 +1,3 @@
-
 # Emitter expects events obeying the following grammar:
 # stream ::= STREAM-START document* STREAM-END
 # document ::= DOCUMENT-START node DOCUMENT-END
@@ -609,7 +608,7 @@ class Emitter:
             chunks.append(suffix[start:end])
         suffix_text = ''.join(chunks)
         if handle:
-            return '%s%s' % (handle, suffix_text)
+            return '{}{}'.format(handle, suffix_text)
         else:
             return '!<%s>' % suffix_text
 
@@ -842,7 +841,7 @@ class Emitter:
         self.write_line_break()
 
     def write_tag_directive(self, handle_text, prefix_text):
-        data = '%%TAG %s %s' % (handle_text, prefix_text)
+        data = '%TAG {} {}'.format(handle_text, prefix_text)
         if self.encoding:
             data = data.encode(self.encoding)
         self.stream.write(data)
diff --git a/python/pyyaml/lib3/yaml/error.py b/python/pyyaml/lib3/yaml/error.py
index b796b4dc51..10f8835421 100644
--- a/python/pyyaml/lib3/yaml/error.py
+++ b/python/pyyaml/lib3/yaml/error.py
@@ -1,4 +1,3 @@
-
 __all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
 
 class Mark:
diff --git a/python/pyyaml/lib3/yaml/events.py b/python/pyyaml/lib3/yaml/events.py
index f79ad389cb..e54499400a 100644
--- a/python/pyyaml/lib3/yaml/events.py
+++ b/python/pyyaml/lib3/yaml/events.py
@@ -1,16 +1,15 @@
-
 # Abstract classes.
 
-class Event(object):
+class Event:
     def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
     def __repr__(self):
         attributes = [key for key in ['anchor', 'tag', 'implicit', 'value']
                 if hasattr(self, key)]
-        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
+        arguments = ', '.join(['{}={!r}'.format(key, getattr(self, key))
                 for key in attributes])
-        return '%s(%s)' % (self.__class__.__name__, arguments)
+        return '{}({})'.format(self.__class__.__name__, arguments)
 
 class NodeEvent(Event):
     def __init__(self, anchor, start_mark=None, end_mark=None):
diff --git a/python/pyyaml/lib3/yaml/loader.py b/python/pyyaml/lib3/yaml/loader.py
index 08c8f01b34..559275b02a 100644
--- a/python/pyyaml/lib3/yaml/loader.py
+++ b/python/pyyaml/lib3/yaml/loader.py
@@ -1,4 +1,3 @@
-
 __all__ = ['BaseLoader', 'SafeLoader', 'Loader']
 
 from .reader import *
diff --git a/python/pyyaml/lib3/yaml/nodes.py b/python/pyyaml/lib3/yaml/nodes.py
index c4f070c41e..c9a20df12a 100644
--- a/python/pyyaml/lib3/yaml/nodes.py
+++ b/python/pyyaml/lib3/yaml/nodes.py
@@ -1,5 +1,4 @@
-
-class Node(object):
+class Node:
     def __init__(self, tag, value, start_mark, end_mark):
         self.tag = tag
         self.value = value
@@ -20,7 +19,7 @@ class Node(object):
         #    else:
         #        value = repr(value)
         value = repr(value)
-        return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value)
+        return '{}(tag={!r}, value={})'.format(self.__class__.__name__, self.tag, value)
 
 class ScalarNode(Node):
     id = 'scalar'
diff --git a/python/pyyaml/lib3/yaml/parser.py b/python/pyyaml/lib3/yaml/parser.py
index 13a5995d29..086838d1b2 100644
--- a/python/pyyaml/lib3/yaml/parser.py
+++ b/python/pyyaml/lib3/yaml/parser.py
@@ -1,4 +1,3 @@
-
 # The following YAML grammar is LL(1) and is parsed by a recursive descent
 # parser.
 #
diff --git a/python/pyyaml/lib3/yaml/reader.py b/python/pyyaml/lib3/yaml/reader.py
index f70e920f44..f4f64d084e 100644
--- a/python/pyyaml/lib3/yaml/reader.py
+++ b/python/pyyaml/lib3/yaml/reader.py
@@ -42,7 +42,7 @@ class ReaderError(YAMLError):
                     % (self.character, self.reason,
                             self.name, self.position)
 
-class Reader(object):
+class Reader:
     # Reader:
     # - determines the data encoding and converts it to a unicode string,
     # - checks if characters are in allowed range,
diff --git a/python/pyyaml/lib3/yaml/representer.py b/python/pyyaml/lib3/yaml/representer.py
index 67cd6fd25e..513c0b1187 100644
--- a/python/pyyaml/lib3/yaml/representer.py
+++ b/python/pyyaml/lib3/yaml/representer.py
@@ -1,4 +1,3 @@
-
 __all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
     'RepresenterError']
 
@@ -273,16 +272,16 @@ class Representer(SafeRepresenter):
         elif data.real == 0.0:
             data = '%rj' % data.imag
         elif data.imag > 0:
-            data = '%r+%rj' % (data.real, data.imag)
+            data = '{!r}+{!r}j'.format(data.real, data.imag)
         else:
-            data = '%r%rj' % (data.real, data.imag)
+            data = '{!r}{!r}j'.format(data.real, data.imag)
         return self.represent_scalar('tag:yaml.org,2002:python/complex', data)
 
     def represent_tuple(self, data):
         return self.represent_sequence('tag:yaml.org,2002:python/tuple', data)
 
     def represent_name(self, data):
-        name = '%s.%s' % (data.__module__, data.__name__)
+        name = '{}.{}'.format(data.__module__, data.__name__)
         return self.represent_scalar('tag:yaml.org,2002:python/name:'+name, '')
 
     def represent_module(self, data):
@@ -332,7 +331,7 @@ class Representer(SafeRepresenter):
         else:
             tag = 'tag:yaml.org,2002:python/object/apply:'
             newobj = False
-        function_name = '%s.%s' % (function.__module__, function.__name__)
+        function_name = '{}.{}'.format(function.__module__, function.__name__)
         if not args and not listitems and not dictitems \
                 and isinstance(state, dict) and newobj:
             return self.represent_mapping(
diff --git a/python/pyyaml/lib3/yaml/resolver.py b/python/pyyaml/lib3/yaml/resolver.py
index 0eece25821..3df59e3346 100644
--- a/python/pyyaml/lib3/yaml/resolver.py
+++ b/python/pyyaml/lib3/yaml/resolver.py
@@ -1,4 +1,3 @@
-
 __all__ = ['BaseResolver', 'Resolver']
 
 from .error import *
diff --git a/python/pyyaml/lib3/yaml/scanner.py b/python/pyyaml/lib3/yaml/scanner.py
index 494d975ba6..695b14bb05 100644
--- a/python/pyyaml/lib3/yaml/scanner.py
+++ b/python/pyyaml/lib3/yaml/scanner.py
@@ -1,4 +1,3 @@
-
 # Scanner produces tokens of the following types:
 # STREAM-START
 # STREAM-END
diff --git a/python/pyyaml/lib3/yaml/serializer.py b/python/pyyaml/lib3/yaml/serializer.py
index fe911e67ae..89eb64e5eb 100644
--- a/python/pyyaml/lib3/yaml/serializer.py
+++ b/python/pyyaml/lib3/yaml/serializer.py
@@ -1,4 +1,3 @@
-
 __all__ = ['Serializer', 'SerializerError']
 
 from .error import YAMLError
diff --git a/python/pyyaml/lib3/yaml/tokens.py b/python/pyyaml/lib3/yaml/tokens.py
index 4d0b48a394..93f5700e28 100644
--- a/python/pyyaml/lib3/yaml/tokens.py
+++ b/python/pyyaml/lib3/yaml/tokens.py
@@ -1,5 +1,4 @@
-
-class Token(object):
+class Token:
     def __init__(self, start_mark, end_mark):
         self.start_mark = start_mark
         self.end_mark = end_mark
@@ -7,9 +6,9 @@ class Token(object):
         attributes = [key for key in self.__dict__
                 if not key.endswith('_mark')]
         attributes.sort()
-        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
+        arguments = ', '.join(['{}={!r}'.format(key, getattr(self, key))
                 for key in attributes])
-        return '%s(%s)' % (self.__class__.__name__, arguments)
+        return '{}({})'.format(self.__class__.__name__, arguments)
 
 #class BOMToken(Token):
 #    id = ''
diff --git a/python/pyyaml/setup.py b/python/pyyaml/setup.py
index 727c3e06ea..d08d0713d0 100644
--- a/python/pyyaml/setup.py
+++ b/python/pyyaml/setup.py
@@ -1,4 +1,3 @@
-
 NAME = 'PyYAML'
 VERSION = '3.11'
 DESCRIPTION = "YAML parser and emitter for Python"
@@ -19,7 +18,7 @@ AUTHOR_EMAIL = 'xi@resolvent.net'
 LICENSE = "MIT"
 PLATFORMS = "Any"
 URL = "http://pyyaml.org/wiki/PyYAML"
-DOWNLOAD_URL = "http://pyyaml.org/download/pyyaml/%s-%s.tar.gz" % (NAME, VERSION)
+DOWNLOAD_URL = "http://pyyaml.org/download/pyyaml/{}-{}.tar.gz".format(NAME, VERSION)
 CLASSIFIERS = [
     "Development Status :: 5 - Production/Stable",
     "Intended Audience :: Developers",
@@ -75,22 +74,6 @@ if 'setuptools.extension' in sys.modules:
     sys.modules['distutils.command.build_ext'].Extension = _Extension
 
 with_pyrex = None
-if sys.version_info[0] < 3:
-    try:
-        from Cython.Distutils.extension import Extension as _Extension
-        from Cython.Distutils import build_ext as _build_ext
-        with_pyrex = 'cython'
-    except ImportError:
-        try:
-            # Pyrex cannot build _yaml.c at the moment,
-            # but it may get fixed eventually.
-            from Pyrex.Distutils import Extension as _Extension
-            from Pyrex.Distutils import build_ext as _build_ext
-            with_pyrex = 'pyrex'
-        except ImportError:
-            pass
-
-
 class Distribution(_Distribution):
 
     def __init__(self, attrs=None):
@@ -187,7 +170,7 @@ class build_ext(_build_ext):
                 filenames.append(filename)
                 base = os.path.splitext(filename)[0]
                 for ext in ['c', 'h', 'pyx', 'pxd']:
-                    filename = '%s.%s' % (base, ext)
+                    filename = '{}.{}'.format(base, ext)
                     if filename not in filenames and os.path.isfile(filename):
                         filenames.append(filename)
         return filenames
@@ -303,10 +286,7 @@ class test(Command):
         build_cmd = self.get_finalized_command('build')
         build_cmd.run()
         sys.path.insert(0, build_cmd.build_lib)
-        if sys.version_info[0] < 3:
-            sys.path.insert(0, 'tests/lib')
-        else:
-            sys.path.insert(0, 'tests/lib3')
+        sys.path.insert(0, 'tests/lib3')
         import test_all
         test_all.main([])
 
diff --git a/python/requests/requests/__init__.py b/python/requests/requests/__init__.py
index bd5b5b9749..c438937716 100644
--- a/python/requests/requests/__init__.py
+++ b/python/requests/requests/__init__.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 #   __
 #  /__)  _  _     _   _ _/   _
 # / (   (- (/ (/ (- _)  /  _)
diff --git a/python/requests/requests/adapters.py b/python/requests/requests/adapters.py
index 6266d5be30..2c785296d8 100644
--- a/python/requests/requests/adapters.py
+++ b/python/requests/requests/adapters.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.adapters
 ~~~~~~~~~~~~~~~~~
@@ -16,7 +14,7 @@ from .packages.urllib3.poolmanager import PoolManager, proxy_from_url
 from .packages.urllib3.response import HTTPResponse
 from .packages.urllib3.util import Timeout as TimeoutSauce
 from .packages.urllib3.util.retry import Retry
-from .compat import urlparse, basestring
+from .compat import urlparse
 from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers,
                     prepend_scheme_if_needed, get_auth_from_url, urldefragauth,
                     select_proxy)
@@ -42,11 +40,11 @@ DEFAULT_RETRIES = 0
 DEFAULT_POOL_TIMEOUT = None
 
 
-class BaseAdapter(object):
+class BaseAdapter:
     """The Base Transport Adapter"""
 
     def __init__(self):
-        super(BaseAdapter, self).__init__()
+        super().__init__()
 
     def send(self):
         raise NotImplementedError
@@ -94,7 +92,7 @@ class HTTPAdapter(BaseAdapter):
         self.config = {}
         self.proxy_manager = {}
 
-        super(HTTPAdapter, self).__init__()
+        super().__init__()
 
         self._pool_connections = pool_connections
         self._pool_maxsize = pool_maxsize
@@ -103,8 +101,8 @@ class HTTPAdapter(BaseAdapter):
         self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
 
     def __getstate__(self):
-        return dict((attr, getattr(self, attr, None)) for attr in
-                    self.__attrs__)
+        return {attr: getattr(self, attr, None) for attr in
+                    self.__attrs__}
 
     def __setstate__(self, state):
         # Can't handle by adding 'proxy_manager' to self.__attrs__ because
@@ -197,7 +195,7 @@ class HTTPAdapter(BaseAdapter):
             conn.ca_cert_dir = None
 
         if cert:
-            if not isinstance(cert, basestring):
+            if not isinstance(cert, str):
                 conn.cert_file = cert[0]
                 conn.key_file = cert[1]
             else:
@@ -354,7 +352,7 @@ class HTTPAdapter(BaseAdapter):
                 timeout = TimeoutSauce(connect=connect, read=read)
             except ValueError as e:
                 # this may raise a string formatting error.
-                err = ("Invalid timeout {0}. Pass a (connect, read) "
+                err = ("Invalid timeout {}. Pass a (connect, read) "
                        "timeout tuple, or a single float to set "
                        "both timeouts to the same value".format(timeout))
                 raise ValueError(err)
@@ -422,7 +420,7 @@ class HTTPAdapter(BaseAdapter):
                     low_conn.close()
                     raise
 
-        except (ProtocolError, socket.error) as err:
+        except (ProtocolError, OSError) as err:
             raise ConnectionError(err, request=request)
 
         except MaxRetryError as e:
diff --git a/python/requests/requests/api.py b/python/requests/requests/api.py
index b21a1a4fa7..b43fc55d60 100644
--- a/python/requests/requests/api.py
+++ b/python/requests/requests/api.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.api
 ~~~~~~~~~~~~
@@ -54,7 +52,7 @@ def request(method, url, **kwargs):
 
 
 def get(url, params=None, **kwargs):
-    """Sends a GET request.
+    r"""Sends a GET request.
 
     :param url: URL for the new :class:`Request` object.
     :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
@@ -68,7 +66,7 @@ def get(url, params=None, **kwargs):
 
 
 def options(url, **kwargs):
-    """Sends a OPTIONS request.
+    r"""Sends a OPTIONS request.
 
     :param url: URL for the new :class:`Request` object.
     :param \*\*kwargs: Optional arguments that ``request`` takes.
@@ -81,7 +79,7 @@ def options(url, **kwargs):
 
 
 def head(url, **kwargs):
-    """Sends a HEAD request.
+    r"""Sends a HEAD request.
 
     :param url: URL for the new :class:`Request` object.
     :param \*\*kwargs: Optional arguments that ``request`` takes.
@@ -94,7 +92,7 @@ def head(url, **kwargs):
 
 
 def post(url, data=None, json=None, **kwargs):
-    """Sends a POST request.
+    r"""Sends a POST request.
 
     :param url: URL for the new :class:`Request` object.
     :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
@@ -108,7 +106,7 @@ def post(url, data=None, json=None, **kwargs):
 
 
 def put(url, data=None, **kwargs):
-    """Sends a PUT request.
+    r"""Sends a PUT request.
 
     :param url: URL for the new :class:`Request` object.
     :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
@@ -121,7 +119,7 @@ def put(url, data=None, **kwargs):
 
 
 def patch(url, data=None, **kwargs):
-    """Sends a PATCH request.
+    r"""Sends a PATCH request.
 
     :param url: URL for the new :class:`Request` object.
     :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
@@ -134,7 +132,7 @@ def patch(url, data=None, **kwargs):
 
 
 def delete(url, **kwargs):
-    """Sends a DELETE request.
+    r"""Sends a DELETE request.
 
     :param url: URL for the new :class:`Request` object.
     :param \*\*kwargs: Optional arguments that ``request`` takes.
diff --git a/python/requests/requests/auth.py b/python/requests/requests/auth.py
index 2af55fb5e6..19393872eb 100644
--- a/python/requests/requests/auth.py
+++ b/python/requests/requests/auth.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.auth
 ~~~~~~~~~~~~~
@@ -28,13 +26,13 @@ def _basic_auth_str(username, password):
     """Returns a Basic Auth string."""
 
     authstr = 'Basic ' + to_native_string(
-        b64encode(('%s:%s' % (username, password)).encode('latin1')).strip()
+        b64encode(('{}:{}'.format(username, password)).encode('latin1')).strip()
     )
 
     return authstr
 
 
-class AuthBase(object):
+class AuthBase:
     """Base class that all auth implementations derive from"""
 
     def __call__(self, r):
@@ -103,7 +101,7 @@ class HTTPDigestAuth(AuthBase):
                 return hashlib.sha1(x).hexdigest()
             hash_utf8 = sha_utf8
 
-        KD = lambda s, d: hash_utf8("%s:%s" % (s, d))
+        KD = lambda s, d: hash_utf8("{}:{}".format(s, d))
 
         if hash_utf8 is None:
             return None
@@ -116,8 +114,8 @@ class HTTPDigestAuth(AuthBase):
         if p_parsed.query:
             path += '?' + p_parsed.query
 
-        A1 = '%s:%s:%s' % (self.username, realm, self.password)
-        A2 = '%s:%s' % (method, path)
+        A1 = '{}:{}:{}'.format(self.username, realm, self.password)
+        A2 = '{}:{}'.format(method, path)
 
         HA1 = hash_utf8(A1)
         HA2 = hash_utf8(A2)
@@ -134,12 +132,12 @@ class HTTPDigestAuth(AuthBase):
 
         cnonce = (hashlib.sha1(s).hexdigest()[:16])
         if _algorithm == 'MD5-SESS':
-            HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce))
+            HA1 = hash_utf8('{}:{}:{}'.format(HA1, nonce, cnonce))
 
         if not qop:
-            respdig = KD(HA1, "%s:%s" % (nonce, HA2))
+            respdig = KD(HA1, "{}:{}".format(nonce, HA2))
         elif qop == 'auth' or 'auth' in qop.split(','):
-            noncebit = "%s:%s:%s:%s:%s" % (
+            noncebit = "{}:{}:{}:{}:{}".format(
                 nonce, ncvalue, cnonce, 'auth', HA2
                 )
             respdig = KD(HA1, noncebit)
@@ -159,7 +157,7 @@ class HTTPDigestAuth(AuthBase):
         if entdig:
             base += ', digest="%s"' % entdig
         if qop:
-            base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce)
+            base += ', qop="auth", nc={}, cnonce="{}"'.format(ncvalue, cnonce)
 
         return 'Digest %s' % (base)
 
diff --git a/python/requests/requests/certs.py b/python/requests/requests/certs.py
index 07e6475070..91655f2744 100644
--- a/python/requests/requests/certs.py
+++ b/python/requests/requests/certs.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 """
 certs.py
@@ -11,6 +10,7 @@ If you are packaging Requests, e.g., for a Linux distribution or a managed
 environment, you can change the definition of where() to return a separately
 packaged CA bundle.
 """
+from __future__ import print_function
 import os.path
 
 try:
@@ -22,4 +22,4 @@ except ImportError:
         return os.path.join(os.path.dirname(__file__), 'cacert.pem')
 
 if __name__ == '__main__':
-    print(where())
+    print((where()))
diff --git a/python/requests/requests/compat.py b/python/requests/requests/compat.py
index 70edff7849..0bc47c55f0 100644
--- a/python/requests/requests/compat.py
+++ b/python/requests/requests/compat.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 pythoncompat
 """
@@ -33,19 +31,19 @@ except (ImportError, SyntaxError):
 # ---------
 
 if is_py2:
-    from urllib import quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, proxy_bypass
-    from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
+    from urllib.parse import quote, unquote, quote_plus, unquote_plus, urlencode
+    from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
     from urllib2 import parse_http_list
-    import cookielib
-    from Cookie import Morsel
+    import six.moves.http_cookiejar
+    from six.moves.http_cookies import Morsel
     from StringIO import StringIO
     from .packages.urllib3.packages.ordered_dict import OrderedDict
 
     builtin_str = str
     bytes = str
-    str = unicode
-    basestring = basestring
-    numeric_types = (int, long, float)
+    str = str
+    str = str
+    numeric_types = (int, int, float)
 
 elif is_py3:
     from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
@@ -58,5 +56,5 @@ elif is_py3:
     builtin_str = str
     str = str
     bytes = bytes
-    basestring = (str, bytes)
+    str = (str, bytes)
     numeric_types = (int, float)
diff --git a/python/requests/requests/cookies.py b/python/requests/requests/cookies.py
index b85fd2b626..c9991570a0 100644
--- a/python/requests/requests/cookies.py
+++ b/python/requests/requests/cookies.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 Compatibility code to be able to use `cookielib.CookieJar` with requests.
 
@@ -20,7 +18,7 @@ except ImportError:
     import dummy_threading as threading
 
 
-class MockRequest(object):
+class MockRequest:
     """Wraps a `requests.Request` to mimic a `urllib2.Request`.
 
     The code in `cookielib.CookieJar` expects this interface in order to correctly
@@ -92,7 +90,7 @@ class MockRequest(object):
         return self.get_host()
 
 
-class MockResponse(object):
+class MockResponse:
     """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
 
     ...what? Basically, expose the parsed HTTP headers from the server response
@@ -161,7 +159,7 @@ class CookieConflictError(RuntimeError):
     Use .get and .set and include domain and path args in order to be more specific."""
 
 
-class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
+class RequestsCookieJar(cookielib.CookieJar, collections.abc.MutableMapping):
     """Compatibility class; is a cookielib.CookieJar, but exposes a dict
     interface.
 
@@ -214,7 +212,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
     def keys(self):
         """Dict-like keys() that returns a list of names of cookies from the
         jar. See values() and items()."""
-        return list(self.iterkeys())
+        return list(self.keys())
 
     def itervalues(self):
         """Dict-like itervalues() that returns an iterator of values of cookies
@@ -225,7 +223,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
     def values(self):
         """Dict-like values() that returns a list of values of cookies from the
         jar. See keys() and items()."""
-        return list(self.itervalues())
+        return list(self.values())
 
     def iteritems(self):
         """Dict-like iteritems() that returns an iterator of name-value tuples
@@ -238,7 +236,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
         jar. See keys() and values(). Allows client-code to call
         ``dict(RequestsCookieJar)`` and get a vanilla python dict of key value
         pairs."""
-        return list(self.iteritems())
+        return list(self.items())
 
     def list_domains(self):
         """Utility method to list all the domains in the jar."""
@@ -301,7 +299,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
     def set_cookie(self, cookie, *args, **kwargs):
         if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'):
             cookie.value = cookie.value.replace('\\"', '')
-        return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs)
+        return super().set_cookie(cookie, *args, **kwargs)
 
     def update(self, other):
         """Updates this jar with cookies from another CookieJar or dict-like"""
@@ -309,7 +307,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
             for cookie in other:
                 self.set_cookie(copy.copy(cookie))
         else:
-            super(RequestsCookieJar, self).update(other)
+            super().update(other)
 
     def _find(self, name, domain=None, path=None):
         """Requests uses this method internally to get cookie values. Takes as
@@ -323,7 +321,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
                     if path is None or cookie.path == path:
                         return cookie.value
 
-        raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
+        raise KeyError('name={!r}, domain={!r}, path={!r}'.format(name, domain, path))
 
     def _find_no_duplicates(self, name, domain=None, path=None):
         """Both ``__get_item__`` and ``get`` call this function: it's never
@@ -342,7 +340,7 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
 
         if toReturn:
             return toReturn
-        raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
+        raise KeyError('name={!r}, domain={!r}, path={!r}'.format(name, domain, path))
 
     def __getstate__(self):
         """Unlike a normal CookieJar, this class is pickleable."""
diff --git a/python/requests/requests/exceptions.py b/python/requests/requests/exceptions.py
index ba0b910e31..9ba622e522 100644
--- a/python/requests/requests/exceptions.py
+++ b/python/requests/requests/exceptions.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.exceptions
 ~~~~~~~~~~~~~~~~~~~
@@ -24,7 +22,7 @@ class RequestException(IOError):
         if (response is not None and not self.request and
                 hasattr(response, 'request')):
             self.request = self.response.request
-        super(RequestException, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
 
 
 class HTTPError(RequestException):
diff --git a/python/requests/requests/hooks.py b/python/requests/requests/hooks.py
index 9da94366d7..274929344e 100644
--- a/python/requests/requests/hooks.py
+++ b/python/requests/requests/hooks.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.hooks
 ~~~~~~~~~~~~~~
@@ -15,7 +13,7 @@ Available hooks:
 HOOKS = ['response']
 
 def default_hooks():
-    return dict((event, []) for event in HOOKS)
+    return {event: [] for event in HOOKS}
 
 # TODO: response is the only one
 
diff --git a/python/requests/requests/models.py b/python/requests/requests/models.py
index 4bcbc5484a..36b0c1a632 100644
--- a/python/requests/requests/models.py
+++ b/python/requests/requests/models.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.models
 ~~~~~~~~~~~~~~~
@@ -30,7 +28,7 @@ from .utils import (
     iter_slices, guess_json_utf, super_len, to_native_string)
 from .compat import (
     cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO,
-    is_py2, chardet, builtin_str, basestring)
+    is_py2, chardet, builtin_str, str)
 from .compat import json as complexjson
 from .status_codes import codes
 
@@ -49,7 +47,7 @@ CONTENT_CHUNK_SIZE = 10 * 1024
 ITER_CHUNK_SIZE = 512
 
 
-class RequestEncodingMixin(object):
+class RequestEncodingMixin:
     @property
     def path_url(self):
         """Build the path URL to use."""
@@ -87,7 +85,7 @@ class RequestEncodingMixin(object):
         elif hasattr(data, '__iter__'):
             result = []
             for k, vs in to_key_val_list(data):
-                if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
+                if isinstance(vs, str) or not hasattr(vs, '__iter__'):
                     vs = [vs]
                 for v in vs:
                     if v is not None:
@@ -109,7 +107,7 @@ class RequestEncodingMixin(object):
         """
         if (not files):
             raise ValueError("Files must be provided.")
-        elif isinstance(data, basestring):
+        elif isinstance(data, str):
             raise ValueError("Data must not be a string.")
 
         new_fields = []
@@ -117,7 +115,7 @@ class RequestEncodingMixin(object):
         files = to_key_val_list(files or {})
 
         for field, val in fields:
-            if isinstance(val, basestring) or not hasattr(val, '__iter__'):
+            if isinstance(val, str) or not hasattr(val, '__iter__'):
                 val = [val]
             for v in val:
                 if v is not None:
@@ -158,17 +156,17 @@ class RequestEncodingMixin(object):
         return body, content_type
 
 
-class RequestHooksMixin(object):
+class RequestHooksMixin:
     def register_hook(self, event, hook):
         """Properly register a hook."""
 
         if event not in self.hooks:
             raise ValueError('Unsupported event specified, with event name "%s"' % (event))
 
-        if isinstance(hook, collections.Callable):
+        if isinstance(hook, collections.abc.Callable):
             self.hooks[event].append(hook)
         elif hasattr(hook, '__iter__'):
-            self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable))
+            self.hooks[event].extend(h for h in hook if isinstance(h, collections.abc.Callable))
 
     def deregister_hook(self, event, hook):
         """Deregister a previously registered hook.
@@ -331,7 +329,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
         if isinstance(url, bytes):
             url = url.decode('utf8')
         else:
-            url = unicode(url) if is_py2 else str(url)
+            url = str(url) if is_py2 else str(url)
 
         # Don't do any URL preparation for non-HTTP schemes like `mailto`,
         # `data` etc to work around exceptions from `url_parse`, which
@@ -391,7 +389,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
         enc_params = self._encode_params(params)
         if enc_params:
             if query:
-                query = '%s&%s' % (query, enc_params)
+                query = '{}&{}'.format(query, enc_params)
             else:
                 query = enc_params
 
@@ -423,7 +421,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
 
         is_stream = all([
             hasattr(data, '__iter__'),
-            not isinstance(data, (basestring, list, tuple, dict))
+            not isinstance(data, (str, list, tuple, dict))
         ])
 
         try:
@@ -448,7 +446,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
             else:
                 if data:
                     body = self._encode_params(data)
-                    if isinstance(data, basestring) or hasattr(data, 'read'):
+                    if isinstance(data, str) or hasattr(data, 'read'):
                         content_type = None
                     else:
                         content_type = 'application/x-www-form-urlencoded'
@@ -525,7 +523,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
             self.register_hook(event, hooks[event])
 
 
-class Response(object):
+class Response:
     """The :class:`Response ` object, which contains a
     server's response to an HTTP request.
     """
@@ -536,7 +534,7 @@ class Response(object):
     ]
 
     def __init__(self):
-        super(Response, self).__init__()
+        super().__init__()
 
         self._content = False
         self._content_consumed = False
@@ -589,10 +587,10 @@ class Response(object):
         if not self._content_consumed:
             self.content
 
-        return dict(
-            (attr, getattr(self, attr, None))
+        return {
+            attr: getattr(self, attr, None)
             for attr in self.__attrs__
-        )
+        }
 
     def __setstate__(self, state):
         for name, value in state.items():
@@ -714,8 +712,7 @@ class Response(object):
             else:
                 pending = None
 
-            for line in lines:
-                yield line
+            yield from lines
 
         if pending is not None:
             yield pending
@@ -734,7 +731,7 @@ class Response(object):
                 if self.status_code == 0:
                     self._content = None
                 else:
-                    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
+                    self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''
 
             except AttributeError:
                 self._content = None
@@ -762,7 +759,7 @@ class Response(object):
         encoding = self.encoding
 
         if not self.content:
-            return str('')
+            return ''
 
         # Fallback to auto-detected encoding.
         if self.encoding is None:
@@ -783,7 +780,7 @@ class Response(object):
         return content
 
     def json(self, **kwargs):
-        """Returns the json-encoded content of a response, if any.
+        r"""Returns the json-encoded content of a response, if any.
 
         :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
         """
@@ -831,10 +828,10 @@ class Response(object):
         http_error_msg = ''
 
         if 400 <= self.status_code < 500:
-            http_error_msg = '%s Client Error: %s for url: %s' % (self.status_code, self.reason, self.url)
+            http_error_msg = '{} Client Error: {} for url: {}'.format(self.status_code, self.reason, self.url)
 
         elif 500 <= self.status_code < 600:
-            http_error_msg = '%s Server Error: %s for url: %s' % (self.status_code, self.reason, self.url)
+            http_error_msg = '{} Server Error: {} for url: {}'.format(self.status_code, self.reason, self.url)
 
         if http_error_msg:
             raise HTTPError(http_error_msg, response=self)
diff --git a/python/requests/requests/packages/__init__.py b/python/requests/requests/packages/__init__.py
index 971c2ad024..cb2525372d 100644
--- a/python/requests/requests/packages/__init__.py
+++ b/python/requests/requests/packages/__init__.py
@@ -20,17 +20,16 @@ https://github.com/kennethreitz/requests/pull/2375 for the corresponding pull
 request.
 '''
 
-from __future__ import absolute_import
 import sys
 
 try:
     from . import urllib3
 except ImportError:
-    import urllib3
+    from . import urllib3
     sys.modules['%s.urllib3' % __name__] = urllib3
 
 try:
     from . import chardet
 except ImportError:
-    import chardet
+    from . import chardet
     sys.modules['%s.chardet' % __name__] = chardet
diff --git a/python/requests/requests/packages/chardet/__init__.py b/python/requests/requests/packages/chardet/__init__.py
index 82c2a48d29..09d2a3991f 100644
--- a/python/requests/requests/packages/chardet/__init__.py
+++ b/python/requests/requests/packages/chardet/__init__.py
@@ -20,7 +20,7 @@ from sys import version_info
 
 
 def detect(aBuf):
-    if ((version_info < (3, 0) and isinstance(aBuf, unicode)) or
+    if ((version_info < (3, 0) and isinstance(aBuf, str)) or
             (version_info >= (3, 0) and not isinstance(aBuf, bytes))):
         raise ValueError('Expected a bytes object, not a unicode object')
 
diff --git a/python/requests/requests/packages/chardet/chardetect.py b/python/requests/requests/packages/chardet/chardetect.py
index ffe892f25d..59549cc9ee 100755
--- a/python/requests/requests/packages/chardet/chardetect.py
+++ b/python/requests/requests/packages/chardet/chardetect.py
@@ -13,11 +13,9 @@ If no paths are provided, it takes its input from stdin.
 
 """
 
-from __future__ import absolute_import, print_function, unicode_literals
 
 import argparse
 import sys
-from io import open
 
 from chardet import __version__
 from chardet.universaldetector import UniversalDetector
@@ -39,10 +37,10 @@ def description_of(lines, name='stdin'):
     u.close()
     result = u.result
     if result['encoding']:
-        return '{0}: {1} with confidence {2}'.format(name, result['encoding'],
+        return '{}: {} with confidence {}'.format(name, result['encoding'],
                                                      result['confidence'])
     else:
-        return '{0}: no result'.format(name)
+        return '{}: no result'.format(name)
 
 
 def main(argv=None):
@@ -64,7 +62,7 @@ def main(argv=None):
                         type=argparse.FileType('rb'), nargs='*',
                         default=[sys.stdin])
     parser.add_argument('--version', action='version',
-                        version='%(prog)s {0}'.format(__version__))
+                        version='%(prog)s {}'.format(__version__))
     args = parser.parse_args(argv)
 
     for f in args.input:
diff --git a/python/requests/requests/packages/chardet/compat.py b/python/requests/requests/packages/chardet/compat.py
index d9e30addf9..6c6ad50416 100644
--- a/python/requests/requests/packages/chardet/compat.py
+++ b/python/requests/requests/packages/chardet/compat.py
@@ -21,10 +21,7 @@
 import sys
 
 
-if sys.version_info < (3, 0):
-    base_str = (str, unicode)
-else:
-    base_str = (bytes, str)
+base_str = (bytes, str)
 
 
 def wrap_ord(a):
diff --git a/python/requests/requests/packages/urllib3/__init__.py b/python/requests/requests/packages/urllib3/__init__.py
index e43991a974..c1123aae8d 100644
--- a/python/requests/requests/packages/urllib3/__init__.py
+++ b/python/requests/requests/packages/urllib3/__init__.py
@@ -2,7 +2,6 @@
 urllib3 - Thread-safe connection pooling and re-using.
 """
 
-from __future__ import absolute_import
 import warnings
 
 from .connectionpool import (
diff --git a/python/requests/requests/packages/urllib3/_collections.py b/python/requests/requests/packages/urllib3/_collections.py
index 67f3ce994d..1bdbb7d48c 100644
--- a/python/requests/requests/packages/urllib3/_collections.py
+++ b/python/requests/requests/packages/urllib3/_collections.py
@@ -1,5 +1,4 @@
-from __future__ import absolute_import
-from collections import Mapping, MutableMapping
+from collections.abc import Mapping, MutableMapping
 try:
     from threading import RLock
 except ImportError:  # Platform-specific: No threads available
@@ -133,7 +132,7 @@ class HTTPHeaderDict(MutableMapping):
     """
 
     def __init__(self, headers=None, **kwargs):
-        super(HTTPHeaderDict, self).__init__()
+        super().__init__()
         self._container = {}
         if headers is not None:
             if isinstance(headers, HTTPHeaderDict):
@@ -162,8 +161,8 @@ class HTTPHeaderDict(MutableMapping):
             return False
         if not isinstance(other, type(self)):
             other = type(self)(other)
-        return (dict((k.lower(), v) for k, v in self.itermerged()) ==
-                dict((k.lower(), v) for k, v in other.itermerged()))
+        return ({k.lower(): v for k, v in self.itermerged()} ==
+                {k.lower(): v for k, v in other.itermerged()})
 
     def __ne__(self, other):
         return not self.__eq__(other)
@@ -235,11 +234,11 @@ class HTTPHeaderDict(MutableMapping):
         """
         if len(args) > 1:
             raise TypeError("extend() takes at most 1 positional "
-                            "arguments ({0} given)".format(len(args)))
+                            "arguments ({} given)".format(len(args)))
         other = args[0] if len(args) >= 1 else ()
 
         if isinstance(other, HTTPHeaderDict):
-            for key, val in other.iteritems():
+            for key, val in other.items():
                 self.add(key, val)
         elif isinstance(other, Mapping):
             for key in other:
@@ -273,7 +272,7 @@ class HTTPHeaderDict(MutableMapping):
     iget = getlist
 
     def __repr__(self):
-        return "%s(%s)" % (type(self).__name__, dict(self.itermerged()))
+        return "{}({})".format(type(self).__name__, dict(self.itermerged()))
 
     def _copy_from(self, other):
         for key in other:
@@ -302,7 +301,7 @@ class HTTPHeaderDict(MutableMapping):
             yield val[0], ', '.join(val[1:])
 
     def items(self):
-        return list(self.iteritems())
+        return list(self.items())
 
     @classmethod
     def from_httplib(cls, message):  # Python 2
diff --git a/python/requests/requests/packages/urllib3/connection.py b/python/requests/requests/packages/urllib3/connection.py
index 1e4cd41758..4b2de5a4e3 100644
--- a/python/requests/requests/packages/urllib3/connection.py
+++ b/python/requests/requests/packages/urllib3/connection.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import datetime
 import os
 import sys
@@ -11,8 +10,8 @@ try:  # Python 3
     from http.client import HTTPConnection as _HTTPConnection
     from http.client import HTTPException  # noqa: unused in this module
 except ImportError:
-    from httplib import HTTPConnection as _HTTPConnection
-    from httplib import HTTPException  # noqa: unused in this module
+    from six.moves.http_client import HTTPConnection as _HTTPConnection
+    from six.moves.http_client import HTTPException  # noqa: unused in this module
 
 try:  # Compiled with SSL?
     import ssl
@@ -58,12 +57,12 @@ port_by_scheme = {
 RECENT_DATE = datetime.date(2014, 1, 1)
 
 
-class DummyConnection(object):
+class DummyConnection:
     """Used to detect a failed ConnectionCls import."""
     pass
 
 
-class HTTPConnection(_HTTPConnection, object):
+class HTTPConnection(_HTTPConnection):
     """
     Based on httplib.HTTPConnection but provides an extra constructor
     backwards-compatibility layer between older and newer Pythons.
@@ -100,8 +99,7 @@ class HTTPConnection(_HTTPConnection, object):
     is_verified = False
 
     def __init__(self, *args, **kw):
-        if six.PY3:  # Python 3
-            kw.pop('strict', None)
+        kw.pop('strict', None)
 
         # Pre-set source_address in case we have an older Python like 2.6.
         self.source_address = kw.get('source_address')
@@ -237,7 +235,7 @@ class VerifiedHTTPSConnection(HTTPSConnection):
         is_time_off = datetime.date.today() < RECENT_DATE
         if is_time_off:
             warnings.warn((
-                'System time is way off (before {0}). This will probably '
+                'System time is way off (before {}). This will probably '
                 'lead to SSL verification errors').format(RECENT_DATE),
                 SystemTimeWarning
             )
@@ -259,7 +257,7 @@ class VerifiedHTTPSConnection(HTTPSConnection):
             cert = self.sock.getpeercert()
             if not cert.get('subjectAltName', ()):
                 warnings.warn((
-                    'Certificate for {0} has no `subjectAltName`, falling back to check for a '
+                    'Certificate for {} has no `subjectAltName`, falling back to check for a '
                     '`commonName` for now. This feature is being removed by major browsers and '
                     'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 '
                     'for details.)'.format(hostname)),
diff --git a/python/requests/requests/packages/urllib3/connectionpool.py b/python/requests/requests/packages/urllib3/connectionpool.py
index 995b4167b5..67e755f303 100644
--- a/python/requests/requests/packages/urllib3/connectionpool.py
+++ b/python/requests/requests/packages/urllib3/connectionpool.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import errno
 import logging
 import sys
@@ -10,9 +9,9 @@ import socket
 try:  # Python 3
     from queue import LifoQueue, Empty, Full
 except ImportError:
-    from Queue import LifoQueue, Empty, Full
+    from queue import LifoQueue, Empty, Full
     # Queue is imported for side effects on MS Windows
-    import Queue as _unused_module_Queue  # noqa: unused
+    import six.moves.queue as _unused_module_Queue  # noqa: unused
 
 
 from .exceptions import (
@@ -48,7 +47,7 @@ from .util.timeout import Timeout
 from .util.url import get_host, Url
 
 
-xrange = six.moves.xrange
+xrange = range
 
 log = logging.getLogger(__name__)
 
@@ -56,7 +55,7 @@ _Default = object()
 
 
 # Pool objects
-class ConnectionPool(object):
+class ConnectionPool:
     """
     Base class for all connection pools, such as
     :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.
@@ -73,7 +72,7 @@ class ConnectionPool(object):
         self.port = port
 
     def __str__(self):
-        return '%s(host=%r, port=%r)' % (type(self).__name__,
+        return '{}(host={!r}, port={!r})'.format(type(self).__name__,
                                          self.host, self.port)
 
     def __enter__(self):
@@ -92,11 +91,11 @@ class ConnectionPool(object):
 
 
 # This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
-_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK])
+_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
 
 
 class HTTPConnectionPool(ConnectionPool, RequestMethods):
-    """
+    r"""
     Thread-safe connection pool for one host.
 
     :param host:
@@ -184,7 +183,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
         self.proxy_headers = _proxy_headers or {}
 
         # Fill the queue up so that doing get() on it will block properly
-        for _ in xrange(maxsize):
+        for _ in range(maxsize):
             self.pool.put(None)
 
         # These are mostly for testing and debugging purposes.
@@ -382,7 +381,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
 
         # AppEngine doesn't have a version attr.
         http_version = getattr(conn, '_http_vsn_str', 'HTTP/?')
-        log.debug("\"%s %s %s\" %s %s" % (method, url, http_version,
+        log.debug("\"{} {} {}\" {} {}".format(method, url, http_version,
                                           httplib_response.status,
                                           httplib_response.length))
 
@@ -436,7 +435,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
     def urlopen(self, method, url, body=None, headers=None, retries=None,
                 redirect=True, assert_same_host=True, timeout=_Default,
                 pool_timeout=None, release_conn=None, **response_kw):
-        """
+        r"""
         Get a connection from the pool and perform an HTTP request. This is the
         lowest level call for making a request, so you'll need to specify all
         the raw details.
@@ -644,7 +643,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
                     raise
                 return response
 
-            log.info("Redirecting %s -> %s" % (url, redirect_location))
+            log.info("Redirecting {} -> {}".format(url, redirect_location))
             return self.urlopen(
                 method, redirect_location, body, headers,
                 retries=retries, redirect=redirect,
@@ -777,7 +776,7 @@ class HTTPSConnectionPool(HTTPConnectionPool):
         """
         Called right before a request is made, after the socket is created.
         """
-        super(HTTPSConnectionPool, self)._validate_conn(conn)
+        super()._validate_conn(conn)
 
         # Force connect early to allow us to validate the connection.
         if not getattr(conn, 'sock', None):  # AppEngine might not have  `.sock`
@@ -792,7 +791,7 @@ class HTTPSConnectionPool(HTTPConnectionPool):
 
 
 def connection_from_url(url, **kw):
-    """
+    r"""
     Given a url, return an :class:`.ConnectionPool` instance of its host.
 
     This is a shortcut for not having to parse out the scheme, host, and port
diff --git a/python/requests/requests/packages/urllib3/contrib/appengine.py b/python/requests/requests/packages/urllib3/contrib/appengine.py
index 884cdb220d..06390643f0 100644
--- a/python/requests/requests/packages/urllib3/contrib/appengine.py
+++ b/python/requests/requests/packages/urllib3/contrib/appengine.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import logging
 import os
 import warnings
diff --git a/python/requests/requests/packages/urllib3/contrib/ntlmpool.py b/python/requests/requests/packages/urllib3/contrib/ntlmpool.py
index c136a238db..4ebd26722c 100644
--- a/python/requests/requests/packages/urllib3/contrib/ntlmpool.py
+++ b/python/requests/requests/packages/urllib3/contrib/ntlmpool.py
@@ -3,12 +3,11 @@ NTLM authenticating pool, contributed by erikcederstran
 
 Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
 """
-from __future__ import absolute_import
 
 try:
     from http.client import HTTPSConnection
 except ImportError:
-    from httplib import HTTPSConnection
+    from six.moves.http_client import HTTPSConnection
 from logging import getLogger
 from ntlm import ntlm
 
@@ -31,7 +30,7 @@ class NTLMConnectionPool(HTTPSConnectionPool):
         user is the Windows user, probably in the DOMAIN\\username format.
         pw is the password for the user.
         """
-        super(NTLMConnectionPool, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
         self.authurl = authurl
         self.rawuser = user
         user_parts = user.split('\\', 1)
@@ -60,7 +59,7 @@ class NTLMConnectionPool(HTTPSConnectionPool):
         conn.request('GET', self.authurl, None, headers)
         res = conn.getresponse()
         reshdr = dict(res.getheaders())
-        log.debug('Response status: %s %s' % (res.status, res.reason))
+        log.debug('Response status: {} {}'.format(res.status, res.reason))
         log.debug('Response headers: %s' % reshdr)
         log.debug('Response data: %s [...]' % res.read(100))
 
@@ -90,7 +89,7 @@ class NTLMConnectionPool(HTTPSConnectionPool):
         log.debug('Request headers: %s' % headers)
         conn.request('GET', self.authurl, None, headers)
         res = conn.getresponse()
-        log.debug('Response status: %s %s' % (res.status, res.reason))
+        log.debug('Response status: {} {}'.format(res.status, res.reason))
         log.debug('Response headers: %s' % dict(res.getheaders()))
         log.debug('Response data: %s [...]' % res.read()[:100])
         if res.status != 200:
@@ -109,7 +108,7 @@ class NTLMConnectionPool(HTTPSConnectionPool):
         if headers is None:
             headers = {}
         headers['Connection'] = 'Keep-Alive'
-        return super(NTLMConnectionPool, self).urlopen(method, url, body,
+        return super().urlopen(method, url, body,
                                                        headers, retries,
                                                        redirect,
                                                        assert_same_host)
diff --git a/python/requests/requests/packages/urllib3/contrib/pyopenssl.py b/python/requests/requests/packages/urllib3/contrib/pyopenssl.py
index 5996153afe..ba3d83814b 100644
--- a/python/requests/requests/packages/urllib3/contrib/pyopenssl.py
+++ b/python/requests/requests/packages/urllib3/contrib/pyopenssl.py
@@ -43,7 +43,6 @@ Module Variables
 .. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
 
 '''
-from __future__ import absolute_import
 
 try:
     from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT
@@ -155,7 +154,7 @@ def get_subj_alt_name(peer_cert):
     return dns_name
 
 
-class WrappedSocket(object):
+class WrappedSocket:
     '''API-compatibility wrapper for Python OpenSSL's Connection-class.
 
     Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
diff --git a/python/requests/requests/packages/urllib3/exceptions.py b/python/requests/requests/packages/urllib3/exceptions.py
index 8e07eb6198..eeb9927f1d 100644
--- a/python/requests/requests/packages/urllib3/exceptions.py
+++ b/python/requests/requests/packages/urllib3/exceptions.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 # Base Exceptions
 
 
@@ -16,7 +15,7 @@ class PoolError(HTTPError):
     "Base exception for errors caused within a pool."
     def __init__(self, pool, message):
         self.pool = pool
-        HTTPError.__init__(self, "%s: %s" % (pool, message))
+        HTTPError.__init__(self, "{}: {}".format(pool, message))
 
     def __reduce__(self):
         # For pickling purposes.
@@ -73,7 +72,7 @@ class MaxRetryError(RequestError):
     def __init__(self, pool, url, reason=None):
         self.reason = reason
 
-        message = "Max retries exceeded with url: %s (Caused by %r)" % (
+        message = "Max retries exceeded with url: {} (Caused by {!r})".format(
             url, reason)
 
         RequestError.__init__(self, pool, url, message)
@@ -191,11 +190,11 @@ class ProxySchemeUnknown(AssertionError, ValueError):
 
     def __init__(self, scheme):
         message = "Not supported proxy scheme %s" % scheme
-        super(ProxySchemeUnknown, self).__init__(message)
+        super().__init__(message)
 
 
 class HeaderParsingError(HTTPError):
     "Raised by assert_header_parsing, but we convert it to a log.warning statement."
     def __init__(self, defects, unparsed_data):
-        message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data)
-        super(HeaderParsingError, self).__init__(message)
+        message = '{}, unparsed data: {!r}'.format(defects or 'Unknown', unparsed_data)
+        super().__init__(message)
diff --git a/python/requests/requests/packages/urllib3/fields.py b/python/requests/requests/packages/urllib3/fields.py
index c7d48113bd..b7d7cd89aa 100644
--- a/python/requests/requests/packages/urllib3/fields.py
+++ b/python/requests/requests/packages/urllib3/fields.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import email.utils
 import mimetypes
 
@@ -33,21 +32,21 @@ def format_header_param(name, value):
         The value of the parameter, provided as a unicode string.
     """
     if not any(ch in value for ch in '"\\\r\n'):
-        result = '%s="%s"' % (name, value)
+        result = '{}="{}"'.format(name, value)
         try:
             result.encode('ascii')
         except UnicodeEncodeError:
             pass
         else:
             return result
-    if not six.PY3:  # Python 2:
+    if not True:  # Python 2:
         value = value.encode('utf-8')
     value = email.utils.encode_rfc2231(value, 'utf-8')
-    value = '%s*=%s' % (name, value)
+    value = '{}*={}'.format(name, value)
     return value
 
 
-class RequestField(object):
+class RequestField:
     """
     A data container for request body parameters.
 
@@ -127,7 +126,7 @@ class RequestField(object):
         parts = []
         iterable = header_parts
         if isinstance(header_parts, dict):
-            iterable = header_parts.items()
+            iterable = list(header_parts.items())
 
         for name, value in iterable:
             if value:
@@ -144,12 +143,12 @@ class RequestField(object):
         sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location']
         for sort_key in sort_keys:
             if self.headers.get(sort_key, False):
-                lines.append('%s: %s' % (sort_key, self.headers[sort_key]))
+                lines.append('{}: {}'.format(sort_key, self.headers[sort_key]))
 
         for header_name, header_value in self.headers.items():
             if header_name not in sort_keys:
                 if header_value:
-                    lines.append('%s: %s' % (header_name, header_value))
+                    lines.append('{}: {}'.format(header_name, header_value))
 
         lines.append('\r\n')
         return '\r\n'.join(lines)
diff --git a/python/requests/requests/packages/urllib3/filepost.py b/python/requests/requests/packages/urllib3/filepost.py
index 97a2843ca4..b7cf71454a 100644
--- a/python/requests/requests/packages/urllib3/filepost.py
+++ b/python/requests/requests/packages/urllib3/filepost.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import codecs
 
 from uuid import uuid4
@@ -27,7 +26,7 @@ def iter_field_objects(fields):
 
     """
     if isinstance(fields, dict):
-        i = six.iteritems(fields)
+        i = list(fields.items())
     else:
         i = iter(fields)
 
@@ -51,7 +50,7 @@ def iter_fields(fields):
     Supports list of (k, v) tuples and dicts.
     """
     if isinstance(fields, dict):
-        return ((k, v) for k, v in six.iteritems(fields))
+        return ((k, v) for k, v in fields.items())
 
     return ((k, v) for k, v in fields)
 
@@ -80,7 +79,7 @@ def encode_multipart_formdata(fields, boundary=None):
         if isinstance(data, int):
             data = str(data)  # Backwards compatibility
 
-        if isinstance(data, six.text_type):
+        if isinstance(data, str):
             writer(body).write(data)
         else:
             body.write(data)
diff --git a/python/requests/requests/packages/urllib3/packages/__init__.py b/python/requests/requests/packages/urllib3/packages/__init__.py
index 170e974c15..2fdf1ea04d 100644
--- a/python/requests/requests/packages/urllib3/packages/__init__.py
+++ b/python/requests/requests/packages/urllib3/packages/__init__.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
 from . import ssl_match_hostname
 
 __all__ = ('ssl_match_hostname', )
diff --git a/python/requests/requests/packages/urllib3/packages/ordered_dict.py b/python/requests/requests/packages/urllib3/packages/ordered_dict.py
index 4479363cc4..816f97c53e 100644
--- a/python/requests/requests/packages/urllib3/packages/ordered_dict.py
+++ b/python/requests/requests/packages/urllib3/packages/ordered_dict.py
@@ -3,9 +3,9 @@
 # Copyright 2009 Raymond Hettinger, released under the MIT License.
 # http://code.activestate.com/recipes/576693/
 try:
-    from thread import get_ident as _get_ident
+    from _thread import get_ident as _get_ident
 except ImportError:
-    from dummy_thread import get_ident as _get_ident
+    from six.moves._dummy_thread import get_ident as _get_ident
 
 try:
     from _abcoll import KeysView, ValuesView, ItemsView
@@ -79,7 +79,7 @@ class OrderedDict(dict):
     def clear(self):
         'od.clear() -> None.  Remove all items from od.'
         try:
-            for node in self.__map.itervalues():
+            for node in self.__map.values():
                 del node[:]
             root = self.__root
             root[:] = [root, root, None]
@@ -202,8 +202,8 @@ class OrderedDict(dict):
         _repr_running[call_key] = 1
         try:
             if not self:
-                return '%s()' % (self.__class__.__name__,)
-            return '%s(%r)' % (self.__class__.__name__, self.items())
+                return '{}()'.format(self.__class__.__name__)
+            return '{}({!r})'.format(self.__class__.__name__, list(self.items()))
         finally:
             del _repr_running[call_key]
 
@@ -238,7 +238,7 @@ class OrderedDict(dict):
 
         '''
         if isinstance(other, OrderedDict):
-            return len(self)==len(other) and self.items() == other.items()
+            return len(self)==len(other) and list(self.items()) == list(other.items())
         return dict.__eq__(self, other)
 
     def __ne__(self, other):
diff --git a/python/requests/requests/packages/urllib3/packages/six.py b/python/requests/requests/packages/urllib3/packages/six.py
index 27d80112bf..6ad7ea98a1 100644
--- a/python/requests/requests/packages/urllib3/packages/six.py
+++ b/python/requests/requests/packages/urllib3/packages/six.py
@@ -22,6 +22,7 @@
 import operator
 import sys
 import types
+from . import six
 
 __author__ = "Benjamin Peterson "
 __version__ = "1.2.0"  # Revision 41c74fef2ded
@@ -39,10 +40,10 @@ if PY3:
 
     MAXSIZE = sys.maxsize
 else:
-    string_types = basestring,
-    integer_types = (int, long)
-    class_types = (type, types.ClassType)
-    text_type = unicode
+    string_types = str,
+    integer_types = int
+    class_types = (type, type)
+    text_type = str
     binary_type = str
 
     if sys.platform.startswith("java"):
@@ -50,7 +51,7 @@ else:
         MAXSIZE = int((1 << 31) - 1)
     else:
         # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
-        class X(object):
+        class X:
             def __len__(self):
                 return 1 << 31
         try:
@@ -75,7 +76,7 @@ def _import_module(name):
     return sys.modules[name]
 
 
-class _LazyDescr(object):
+class _LazyDescr:
 
     def __init__(self, name):
         self.name = name
@@ -91,7 +92,7 @@ class _LazyDescr(object):
 class MovedModule(_LazyDescr):
 
     def __init__(self, name, old, new=None):
-        super(MovedModule, self).__init__(name)
+        super().__init__(name)
         if PY3:
             if new is None:
                 new = name
@@ -106,7 +107,7 @@ class MovedModule(_LazyDescr):
 class MovedAttribute(_LazyDescr):
 
     def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
-        super(MovedAttribute, self).__init__(name)
+        super().__init__(name)
         if PY3:
             if new_mod is None:
                 new_mod = name
@@ -199,7 +200,7 @@ def remove_move(name):
         try:
             del moves.__dict__[name]
         except KeyError:
-            raise AttributeError("no such move, %r" % (name,))
+            raise AttributeError("no such move, {!r}".format(name))
 
 
 if PY3:
@@ -228,7 +229,7 @@ try:
     advance_iterator = next
 except NameError:
     def advance_iterator(it):
-        return it.next()
+        return next(it)
 next = advance_iterator
 
 
@@ -242,9 +243,9 @@ if PY3:
         return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
 else:
     def get_unbound_function(unbound):
-        return unbound.im_func
+        return unbound.__func__
 
-    class Iterator(object):
+    class Iterator:
 
         def next(self):
             return type(self).__next__(self)
@@ -291,7 +292,7 @@ else:
     def b(s):
         return s
     def u(s):
-        return unicode(s, "unicode_escape")
+        return str(s, "unicode_escape")
     int2byte = chr
     import StringIO
     StringIO = BytesIO = StringIO.StringIO
@@ -328,7 +329,7 @@ else:
 
 
     exec_("""def reraise(tp, value, tb=None):
-    raise tp, value, tb
+    raise tp(value, tb)
 """)
 
 
@@ -338,19 +339,19 @@ else:
         if fp is None:
             return
         def write(data):
-            if not isinstance(data, basestring):
+            if not isinstance(data, str):
                 data = str(data)
             fp.write(data)
         want_unicode = False
         sep = kwargs.pop("sep", None)
         if sep is not None:
-            if isinstance(sep, unicode):
+            if isinstance(sep, str):
                 want_unicode = True
             elif not isinstance(sep, str):
                 raise TypeError("sep must be None or a string")
         end = kwargs.pop("end", None)
         if end is not None:
-            if isinstance(end, unicode):
+            if isinstance(end, str):
                 want_unicode = True
             elif not isinstance(end, str):
                 raise TypeError("end must be None or a string")
@@ -358,12 +359,12 @@ else:
             raise TypeError("invalid keyword arguments to print()")
         if not want_unicode:
             for arg in args:
-                if isinstance(arg, unicode):
+                if isinstance(arg, str):
                     want_unicode = True
                     break
         if want_unicode:
-            newline = unicode("\n")
-            space = unicode(" ")
+            newline = str("\n")
+            space = str(" ")
         else:
             newline = "\n"
             space = " "
diff --git a/python/requests/requests/packages/urllib3/poolmanager.py b/python/requests/requests/packages/urllib3/poolmanager.py
index f13e673d1f..8e1be95559 100644
--- a/python/requests/requests/packages/urllib3/poolmanager.py
+++ b/python/requests/requests/packages/urllib3/poolmanager.py
@@ -1,10 +1,9 @@
-from __future__ import absolute_import
 import logging
 
 try:  # Python 3
     from urllib.parse import urljoin
 except ImportError:
-    from urlparse import urljoin
+    from urllib.parse import urljoin
 
 from ._collections import RecentlyUsedContainer
 from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool
@@ -30,7 +29,7 @@ SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs',
 
 
 class PoolManager(RequestMethods):
-    """
+    r"""
     Allows for arbitrary requests while transparently keeping track of
     necessary connection pools for you.
 
@@ -186,7 +185,7 @@ class PoolManager(RequestMethods):
         kw['retries'] = retries
         kw['redirect'] = redirect
 
-        log.info("Redirecting %s -> %s" % (url, redirect_location))
+        log.info("Redirecting {} -> {}".format(url, redirect_location))
         return self.urlopen(method, redirect_location, **kw)
 
 
@@ -237,15 +236,15 @@ class ProxyManager(PoolManager):
         connection_pool_kw['_proxy'] = self.proxy
         connection_pool_kw['_proxy_headers'] = self.proxy_headers
 
-        super(ProxyManager, self).__init__(
+        super().__init__(
             num_pools, headers, **connection_pool_kw)
 
     def connection_from_host(self, host, port=None, scheme='http'):
         if scheme == "https":
-            return super(ProxyManager, self).connection_from_host(
+            return super().connection_from_host(
                 host, port, scheme)
 
-        return super(ProxyManager, self).connection_from_host(
+        return super().connection_from_host(
             self.proxy.host, self.proxy.port, self.proxy.scheme)
 
     def _set_proxy_headers(self, url, headers=None):
@@ -274,7 +273,7 @@ class ProxyManager(PoolManager):
             headers = kw.get('headers', self.headers)
             kw['headers'] = self._set_proxy_headers(url, headers)
 
-        return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
+        return super().urlopen(method, url, redirect=redirect, **kw)
 
 
 def proxy_from_url(url, **kw):
diff --git a/python/requests/requests/packages/urllib3/request.py b/python/requests/requests/packages/urllib3/request.py
index d5aa62d887..84e118f18a 100644
--- a/python/requests/requests/packages/urllib3/request.py
+++ b/python/requests/requests/packages/urllib3/request.py
@@ -1,8 +1,7 @@
-from __future__ import absolute_import
 try:
     from urllib.parse import urlencode
 except ImportError:
-    from urllib import urlencode
+    from urllib.parse import urlencode
 
 from .filepost import encode_multipart_formdata
 
@@ -10,7 +9,7 @@ from .filepost import encode_multipart_formdata
 __all__ = ['RequestMethods']
 
 
-class RequestMethods(object):
+class RequestMethods:
     """
     Convenience mixin for classes who implement a :meth:`urlopen` method, such
     as :class:`~urllib3.connectionpool.HTTPConnectionPool` and
@@ -39,7 +38,7 @@ class RequestMethods(object):
         explicitly.
     """
 
-    _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS'])
+    _encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'}
 
     def __init__(self, headers=None):
         self.headers = headers or {}
diff --git a/python/requests/requests/packages/urllib3/response.py b/python/requests/requests/packages/urllib3/response.py
index 8f2a1b5c29..83a6ff539e 100644
--- a/python/requests/requests/packages/urllib3/response.py
+++ b/python/requests/requests/packages/urllib3/response.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 from contextlib import contextmanager
 import zlib
 import io
@@ -9,13 +8,13 @@ from ._collections import HTTPHeaderDict
 from .exceptions import (
     ProtocolError, DecodeError, ReadTimeoutError, ResponseNotChunked
 )
-from .packages.six import string_types as basestring, binary_type, PY3
+from .packages.six import string_types as str, binary_type, PY3
 from .packages.six.moves import http_client as httplib
 from .connection import HTTPException, BaseSSLError
 from .util.response import is_fp_closed, is_response_to_head
 
 
-class DeflateDecoder(object):
+class DeflateDecoder:
 
     def __init__(self):
         self._first_try = True
@@ -44,7 +43,7 @@ class DeflateDecoder(object):
                 self._data = None
 
 
-class GzipDecoder(object):
+class GzipDecoder:
 
     def __init__(self):
         self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
@@ -114,7 +113,7 @@ class HTTPResponse(io.IOBase):
         self._original_response = original_response
         self._fp_bytes_read = 0
 
-        if body and isinstance(body, (basestring, binary_type)):
+        if body and isinstance(body, (str, binary_type)):
             self._body = body
 
         self._pool = pool
@@ -190,7 +189,7 @@ class HTTPResponse(io.IOBase):
         try:
             if decode_content and self._decoder:
                 data = self._decoder.decompress(data)
-        except (IOError, zlib.error) as e:
+        except (OSError, zlib.error) as e:
             content_encoding = self.headers.get('content-encoding', '').lower()
             raise DecodeError(
                 "Received response with content-encoding: %s, but "
@@ -337,8 +336,7 @@ class HTTPResponse(io.IOBase):
             'content-encoding' header.
         """
         if self.chunked:
-            for line in self.read_chunked(amt, decode_content=decode_content):
-                yield line
+            yield from self.read_chunked(amt, decode_content=decode_content)
         else:
             while not is_fp_closed(self._fp):
                 data = self.read(amt=amt, decode_content=decode_content)
@@ -359,7 +357,7 @@ class HTTPResponse(io.IOBase):
 
         if not isinstance(headers, HTTPHeaderDict):
             if PY3:  # Python 3
-                headers = HTTPHeaderDict(headers.items())
+                headers = HTTPHeaderDict(list(headers.items()))
             else:  # Python 2
                 headers = HTTPHeaderDict.from_httplib(headers)
 
@@ -400,11 +398,11 @@ class HTTPResponse(io.IOBase):
 
     def fileno(self):
         if self._fp is None:
-            raise IOError("HTTPResponse has no file to get a fileno from")
+            raise OSError("HTTPResponse has no file to get a fileno from")
         elif hasattr(self._fp, "fileno"):
             return self._fp.fileno()
         else:
-            raise IOError("The file-like object this HTTPResponse is wrapped "
+            raise OSError("The file-like object this HTTPResponse is wrapped "
                           "around has no file descriptor")
 
     def flush(self):
diff --git a/python/requests/requests/packages/urllib3/util/__init__.py b/python/requests/requests/packages/urllib3/util/__init__.py
index c6c6243cf1..ccdf06977a 100644
--- a/python/requests/requests/packages/urllib3/util/__init__.py
+++ b/python/requests/requests/packages/urllib3/util/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 # For backwards compatibility, provide imports that used to be here.
 from .connection import is_connection_dropped
 from .request import make_headers
diff --git a/python/requests/requests/packages/urllib3/util/connection.py b/python/requests/requests/packages/urllib3/util/connection.py
index 01a4812f21..04a04651a4 100644
--- a/python/requests/requests/packages/urllib3/util/connection.py
+++ b/python/requests/requests/packages/urllib3/util/connection.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import socket
 try:
     from select import poll, POLLIN
@@ -32,7 +31,7 @@ def is_connection_dropped(conn):  # Platform-specific
 
         try:
             return select([sock], [], [], 0.0)[0]
-        except socket.error:
+        except OSError:
             return True
 
     # This version is better on platforms that support it.
@@ -81,7 +80,7 @@ def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
             sock.connect(sa)
             return sock
 
-        except socket.error as e:
+        except OSError as e:
             err = e
             if sock is not None:
                 sock.close()
@@ -90,7 +89,7 @@ def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
     if err is not None:
         raise err
 
-    raise socket.error("getaddrinfo returns an empty list")
+    raise OSError("getaddrinfo returns an empty list")
 
 
 def _set_socket_options(sock, options):
diff --git a/python/requests/requests/packages/urllib3/util/request.py b/python/requests/requests/packages/urllib3/util/request.py
index 73779315f4..bc64f6b1fb 100644
--- a/python/requests/requests/packages/urllib3/util/request.py
+++ b/python/requests/requests/packages/urllib3/util/request.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 from base64 import b64encode
 
 from ..packages.six import b
diff --git a/python/requests/requests/packages/urllib3/util/response.py b/python/requests/requests/packages/urllib3/util/response.py
index bc7232720d..2c1de154a4 100644
--- a/python/requests/requests/packages/urllib3/util/response.py
+++ b/python/requests/requests/packages/urllib3/util/response.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 from ..packages.six.moves import http_client as httplib
 
 from ..exceptions import HeaderParsingError
@@ -45,7 +44,7 @@ def assert_header_parsing(headers):
     # This will fail silently if we pass in the wrong kind of parameter.
     # To make debugging easier add an explicit check.
     if not isinstance(headers, httplib.HTTPMessage):
-        raise TypeError('expected httplib.Message, got {0}.'.format(
+        raise TypeError('expected httplib.Message, got {}.'.format(
             type(headers)))
 
     defects = getattr(headers, 'defects', None)
diff --git a/python/requests/requests/packages/urllib3/util/retry.py b/python/requests/requests/packages/urllib3/util/retry.py
index 03a01249dd..732a138e42 100644
--- a/python/requests/requests/packages/urllib3/util/retry.py
+++ b/python/requests/requests/packages/urllib3/util/retry.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import time
 import logging
 
@@ -15,7 +14,7 @@ from ..packages import six
 log = logging.getLogger(__name__)
 
 
-class Retry(object):
+class Retry:
     """ Retry configuration.
 
     Each retry attempt will create a new Retry object with updated values, so
@@ -153,7 +152,7 @@ class Retry(object):
 
         redirect = bool(redirect) and None
         new_retries = cls(retries, redirect=redirect)
-        log.debug("Converted retries value: %r -> %r" % (retries, new_retries))
+        log.debug("Converted retries value: {!r} -> {!r}".format(retries, new_retries))
         return new_retries
 
     def get_backoff_time(self):
@@ -201,7 +200,7 @@ class Retry(object):
     def is_exhausted(self):
         """ Are we out of retries? """
         retry_counts = (self.total, self.connect, self.read, self.redirect)
-        retry_counts = list(filter(None, retry_counts))
+        retry_counts = list([_f for _f in retry_counts if _f])
         if not retry_counts:
             return False
 
@@ -272,7 +271,7 @@ class Retry(object):
         if new_retry.is_exhausted():
             raise MaxRetryError(_pool, url, error or ResponseError(cause))
 
-        log.debug("Incremented Retry for (url='%s'): %r" % (url, new_retry))
+        log.debug("Incremented Retry for (url='{}'): {!r}".format(url, new_retry))
 
         return new_retry
 
diff --git a/python/requests/requests/packages/urllib3/util/ssl_.py b/python/requests/requests/packages/urllib3/util/ssl_.py
index 67f83441e2..e29dff4f3e 100644
--- a/python/requests/requests/packages/urllib3/util/ssl_.py
+++ b/python/requests/requests/packages/urllib3/util/ssl_.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 import errno
 import warnings
 import hmac
@@ -76,7 +75,7 @@ try:
 except ImportError:
     import sys
 
-    class SSLContext(object):  # Platform-specific: Python 2 & 3.1
+    class SSLContext:  # Platform-specific: Python 2 & 3.1
         supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or
                                 (3, 2) <= sys.version_info)
 
@@ -147,7 +146,7 @@ def assert_fingerprint(cert, fingerprint):
     hashfunc = HASHFUNC_MAP.get(digest_length)
     if not hashfunc:
         raise SSLError(
-            'Fingerprint of invalid length: {0}'.format(fingerprint))
+            'Fingerprint of invalid length: {}'.format(fingerprint))
 
     # We need encode() here for py32; works on py2 and p33.
     fingerprint_bytes = unhexlify(fingerprint.encode())
@@ -155,7 +154,7 @@ def assert_fingerprint(cert, fingerprint):
     cert_digest = hashfunc(cert).digest()
 
     if not _const_compare_digest(cert_digest, fingerprint_bytes):
-        raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".'
+        raise SSLError('Fingerprints did not match. Expected "{}", got "{}".'
                        .format(fingerprint, hexlify(cert_digest)))
 
 
@@ -290,7 +289,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
     if ca_certs or ca_cert_dir:
         try:
             context.load_verify_locations(ca_certs, ca_cert_dir)
-        except IOError as e:  # Platform-specific: Python 2.6, 2.7, 3.2
+        except OSError as e:  # Platform-specific: Python 2.6, 2.7, 3.2
             raise SSLError(e)
         # Py33 raises FileNotFoundError which subclasses OSError
         # These are not equivalent unless we check the errno attribute
diff --git a/python/requests/requests/packages/urllib3/util/timeout.py b/python/requests/requests/packages/urllib3/util/timeout.py
index ff62f4764d..bc0b296fac 100644
--- a/python/requests/requests/packages/urllib3/util/timeout.py
+++ b/python/requests/requests/packages/urllib3/util/timeout.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 # The default socket timeout, used by httplib to indicate that no timeout was
 # specified by the user
 from socket import _GLOBAL_DEFAULT_TIMEOUT
@@ -18,7 +17,7 @@ def current_time():
     return time.time()
 
 
-class Timeout(object):
+class Timeout:
     """ Timeout configuration.
 
     Timeouts can be defined as a default for a pool::
@@ -100,7 +99,7 @@ class Timeout(object):
         self._start_connect = None
 
     def __str__(self):
-        return '%s(connect=%r, read=%r, total=%r)' % (
+        return '{}(connect={!r}, read={!r}, total={!r})'.format(
             type(self).__name__, self._connect, self._read, self.total)
 
     @classmethod
diff --git a/python/requests/requests/packages/urllib3/util/url.py b/python/requests/requests/packages/urllib3/util/url.py
index e996204a07..07c77f1a21 100644
--- a/python/requests/requests/packages/urllib3/util/url.py
+++ b/python/requests/requests/packages/urllib3/util/url.py
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
 from collections import namedtuple
 
 from ..exceptions import LocationParseError
@@ -18,7 +17,7 @@ class Url(namedtuple('Url', url_attrs)):
                 query=None, fragment=None):
         if path and not path.startswith('/'):
             path = '/' + path
-        return super(Url, cls).__new__(cls, scheme, auth, host, port, path,
+        return super().__new__(cls, scheme, auth, host, port, path,
                                        query, fragment)
 
     @property
diff --git a/python/requests/requests/sessions.py b/python/requests/requests/sessions.py
index 9eaa36ae43..aaaa8c9def 100644
--- a/python/requests/requests/sessions.py
+++ b/python/requests/requests/sessions.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.session
 ~~~~~~~~~~~~~~~~
@@ -9,7 +7,7 @@ requests (cookies, auth, proxies).
 
 """
 import os
-from collections import Mapping
+from collections.abc import Mapping
 from datetime import datetime
 
 from .auth import _basic_auth_str
@@ -87,7 +85,7 @@ def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
     return merge_setting(request_hooks, session_hooks, dict_class)
 
 
-class SessionRedirectMixin(object):
+class SessionRedirectMixin:
     def resolve_redirects(self, resp, req, stream=False, timeout=None,
                           verify=True, cert=None, proxies=None, **adapter_kwargs):
         """Receives a Response. Returns a generator of Responses."""
@@ -121,7 +119,7 @@ class SessionRedirectMixin(object):
             # Handle redirection without scheme (see: RFC 1808 Section 4)
             if url.startswith('//'):
                 parsed_rurl = urlparse(resp.url)
-                url = '%s:%s' % (parsed_rurl.scheme, url)
+                url = '{}:{}'.format(parsed_rurl.scheme, url)
 
             # The scheme should be lower case...
             parsed = urlparse(url)
@@ -470,7 +468,7 @@ class Session(SessionRedirectMixin):
         return resp
 
     def get(self, url, **kwargs):
-        """Sends a GET request. Returns :class:`Response` object.
+        r"""Sends a GET request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param \*\*kwargs: Optional arguments that ``request`` takes.
@@ -480,7 +478,7 @@ class Session(SessionRedirectMixin):
         return self.request('GET', url, **kwargs)
 
     def options(self, url, **kwargs):
-        """Sends a OPTIONS request. Returns :class:`Response` object.
+        r"""Sends a OPTIONS request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param \*\*kwargs: Optional arguments that ``request`` takes.
@@ -490,7 +488,7 @@ class Session(SessionRedirectMixin):
         return self.request('OPTIONS', url, **kwargs)
 
     def head(self, url, **kwargs):
-        """Sends a HEAD request. Returns :class:`Response` object.
+        r"""Sends a HEAD request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param \*\*kwargs: Optional arguments that ``request`` takes.
@@ -500,7 +498,7 @@ class Session(SessionRedirectMixin):
         return self.request('HEAD', url, **kwargs)
 
     def post(self, url, data=None, json=None, **kwargs):
-        """Sends a POST request. Returns :class:`Response` object.
+        r"""Sends a POST request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
@@ -511,7 +509,7 @@ class Session(SessionRedirectMixin):
         return self.request('POST', url, data=data, json=json, **kwargs)
 
     def put(self, url, data=None, **kwargs):
-        """Sends a PUT request. Returns :class:`Response` object.
+        r"""Sends a PUT request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
@@ -521,7 +519,7 @@ class Session(SessionRedirectMixin):
         return self.request('PUT', url, data=data, **kwargs)
 
     def patch(self, url, data=None, **kwargs):
-        """Sends a PATCH request. Returns :class:`Response` object.
+        r"""Sends a PATCH request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
@@ -531,7 +529,7 @@ class Session(SessionRedirectMixin):
         return self.request('PATCH', url,  data=data, **kwargs)
 
     def delete(self, url, **kwargs):
-        """Sends a DELETE request. Returns :class:`Response` object.
+        r"""Sends a DELETE request. Returns :class:`Response` object.
 
         :param url: URL for the new :class:`Request` object.
         :param \*\*kwargs: Optional arguments that ``request`` takes.
@@ -660,7 +658,7 @@ class Session(SessionRedirectMixin):
             self.adapters[key] = self.adapters.pop(key)
 
     def __getstate__(self):
-        state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__)
+        state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
         state['redirect_cache'] = dict(self.redirect_cache)
         return state
 
diff --git a/python/requests/requests/status_codes.py b/python/requests/requests/status_codes.py
index a852574a45..101b6ff8bb 100644
--- a/python/requests/requests/status_codes.py
+++ b/python/requests/requests/status_codes.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 from .structures import LookupDict
 
 _codes = {
diff --git a/python/requests/requests/structures.py b/python/requests/requests/structures.py
index 3e5f2faa2e..4f941e520f 100644
--- a/python/requests/requests/structures.py
+++ b/python/requests/requests/structures.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.structures
 ~~~~~~~~~~~~~~~~~~~
@@ -9,14 +7,15 @@ Data structures that power Requests.
 """
 
 import collections
+import collections.abc
 
 
-class CaseInsensitiveDict(collections.MutableMapping):
+class CaseInsensitiveDict(collections.abc.MutableMapping):
     """
     A case-insensitive ``dict``-like object.
 
     Implements all methods and operations of
-    ``collections.MutableMapping`` as well as dict's ``copy``. Also
+    ``collections.abc.MutableMapping`` as well as dict's ``copy``. Also
     provides ``lower_items``.
 
     All keys are expected to be strings. The structure remembers the
@@ -71,7 +70,7 @@ class CaseInsensitiveDict(collections.MutableMapping):
         )
 
     def __eq__(self, other):
-        if isinstance(other, collections.Mapping):
+        if isinstance(other, collections.abc.Mapping):
             other = CaseInsensitiveDict(other)
         else:
             return NotImplemented
@@ -80,17 +79,17 @@ class CaseInsensitiveDict(collections.MutableMapping):
 
     # Copy is required
     def copy(self):
-        return CaseInsensitiveDict(self._store.values())
+        return CaseInsensitiveDict(list(self._store.values()))
 
     def __repr__(self):
-        return str(dict(self.items()))
+        return str(dict(list(self.items())))
 
 class LookupDict(dict):
     """Dictionary lookup object."""
 
     def __init__(self, name=None):
         self.name = name
-        super(LookupDict, self).__init__()
+        super().__init__()
 
     def __repr__(self):
         return '' % (self.name)
diff --git a/python/requests/requests/utils.py b/python/requests/requests/utils.py
index c5c3fd01d9..9131b7aac7 100644
--- a/python/requests/requests/utils.py
+++ b/python/requests/requests/utils.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 """
 requests.utils
 ~~~~~~~~~~~~~~
@@ -26,7 +24,7 @@ from . import certs
 from .compat import parse_http_list as _parse_list_header
 from .compat import (quote, urlparse, bytes, str, OrderedDict, unquote, is_py2,
                      builtin_str, getproxies, proxy_bypass, urlunparse,
-                     basestring)
+                     str)
 from .cookies import RequestsCookieJar, cookiejar_from_dict
 from .structures import CaseInsensitiveDict
 from .exceptions import InvalidURL, FileModeWarning
@@ -42,7 +40,7 @@ def dict_to_sequence(d):
     """Returns an internal sequence dictionary update."""
 
     if hasattr(d, 'items'):
-        d = d.items()
+        d = list(d.items())
 
     return d
 
@@ -98,7 +96,7 @@ def get_netrc_auth(url, raise_errors=False):
 
         for f in NETRC_FILES:
             try:
-                loc = os.path.expanduser('~/{0}'.format(f))
+                loc = os.path.expanduser('~/{}'.format(f))
             except KeyError:
                 # os.path.expanduser can fail when $HOME is undefined and
                 # getpwuid fails. See http://bugs.python.org/issue20164 &
@@ -128,7 +126,7 @@ def get_netrc_auth(url, raise_errors=False):
                 # Return with login / password
                 login_i = (0 if _netrc[0] else 1)
                 return (_netrc[login_i], _netrc[2])
-        except (NetrcParseError, IOError):
+        except (NetrcParseError, OSError):
             # If there was a parsing error or a permissions issue reading the file,
             # we'll just skip netrc auth unless explicitly asked to raise errors.
             if raise_errors:
@@ -142,7 +140,7 @@ def get_netrc_auth(url, raise_errors=False):
 def guess_filename(obj):
     """Tries to guess the filename of the given object."""
     name = getattr(obj, 'name', None)
-    if (name and isinstance(name, basestring) and name[0] != '<' and
+    if (name and isinstance(name, str) and name[0] != '<' and
             name[-1] != '>'):
         return os.path.basename(name)
 
@@ -189,8 +187,8 @@ def to_key_val_list(value):
     if isinstance(value, (str, bytes, bool, int)):
         raise ValueError('cannot encode objects that are not 2-tuples')
 
-    if isinstance(value, collections.Mapping):
-        value = value.items()
+    if isinstance(value, collections.abc.Mapping):
+        value = list(value.items())
 
     return list(value)
 
@@ -355,8 +353,7 @@ def stream_decode_response_unicode(iterator, r):
     """Stream decodes a iterator."""
 
     if r.encoding is None:
-        for item in iterator:
-            yield item
+        yield from iterator
         return
 
     decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace')
@@ -485,7 +482,7 @@ def dotted_netmask(mask):
 def is_ipv4_address(string_ip):
     try:
         socket.inet_aton(string_ip)
-    except socket.error:
+    except OSError:
         return False
     return True
 
@@ -503,7 +500,7 @@ def is_valid_cidr(string_network):
 
         try:
             socket.inet_aton(string_network.split('/')[0])
-        except socket.error:
+        except OSError:
             return False
     else:
         return False
@@ -579,7 +576,7 @@ def select_proxy(url, proxies):
 
 def default_user_agent(name="python-requests"):
     """Return a string representing the default user agent."""
-    return '%s/%s' % (name, __version__)
+    return '{}/{}'.format(name, __version__)
 
 
 def default_headers():
diff --git a/python/requests/setup.py b/python/requests/setup.py
index b7ed12ba2c..3d0613c78a 100755
--- a/python/requests/setup.py
+++ b/python/requests/setup.py
@@ -29,7 +29,7 @@ packages = [
 requires = []
 
 version = ''
-with open('requests/__init__.py', 'r') as fd:
+with open('requests/__init__.py') as fd:
     version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
                         fd.read(), re.MULTILINE).group(1)
 
diff --git a/python/requests/test_requests.py b/python/requests/test_requests.py
index 0795241867..25f0f2f832 100755
--- a/python/requests/test_requests.py
+++ b/python/requests/test_requests.py
@@ -1,9 +1,7 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 """Tests for Requests."""
 
-from __future__ import division
 import json
 import os
 import pickle
@@ -74,7 +72,7 @@ def httpsbin_url(httpbin_secure):
 # listening on that port)
 TARPIT = "http://10.255.255.1"
 
-class TestRequests(object):
+class TestRequests:
 
     _multiprocess_can_split_ = True
 
@@ -159,7 +157,7 @@ class TestRequests(object):
 
     def test_binary_put(self):
         request = requests.Request('PUT', 'http://example.com',
-                                   data=u"ööö".encode("utf-8")).prepare()
+                                   data="ööö".encode()).prepare()
         assert isinstance(request.body, bytes)
 
     def test_mixed_case_scheme_acceptable(self, httpbin):
@@ -171,7 +169,7 @@ class TestRequests(object):
             url = scheme + parts.netloc + parts.path
             r = requests.Request('GET', url)
             r = s.send(r.prepare())
-            assert r.status_code == 200, 'failed for scheme {0}'.format(scheme)
+            assert r.status_code == 200, 'failed for scheme {}'.format(scheme)
 
     def test_HTTP_200_OK_GET_ALTERNATIVE(self, httpbin):
         r = requests.Request('GET', httpbin('get'))
@@ -523,7 +521,7 @@ class TestRequests(object):
     def test_unicode_header_name(self, httpbin):
         requests.put(
             httpbin('put'),
-            headers={str('Content-Type'): 'application/octet-stream'},
+            headers={'Content-Type': 'application/octet-stream'},
             data='\xff')  # compat.str is unicode.
 
     def test_pyopenssl_redirect(self, httpsbin_url, httpbin_ca_bundle):
@@ -559,7 +557,7 @@ class TestRequests(object):
         assert r.status_code == 200
 
         r = requests.post(httpbin('post'),
-            data={'stuff': 'elixr'.encode('utf-8')},
+            data={'stuff': b'elixr'},
             files={'file': ('test_requests.py', open(__file__, 'rb'))})
         assert r.status_code == 200
 
@@ -567,7 +565,7 @@ class TestRequests(object):
         filename = os.path.splitext(__file__)[0] + '.py'
         r = requests.Request(method='POST',
                              url=httpbin('post'),
-                             data={'stuff'.encode('utf-8'): 'elixr'},
+                             data={b'stuff': 'elixr'},
                              files={'file': ('test_requests.py',
                                              open(filename, 'rb'))})
         prep = r.prepare()
@@ -719,8 +717,8 @@ class TestRequests(object):
         jar.set(key1, value1)
 
         d1 = dict(jar)
-        d2 = dict(jar.iteritems())
-        d3 = dict(jar.items())
+        d2 = dict(jar.items())
+        d3 = dict(list(jar.items()))
 
         assert len(jar) == 2
         assert len(d1) == 2
@@ -739,8 +737,8 @@ class TestRequests(object):
         jar.set(key1, value1)
 
         d1 = dict(jar)
-        d2 = dict(jar.iteritems())
-        d3 = dict(jar.items())
+        d2 = dict(jar.items())
+        d3 = dict(list(jar.items()))
 
         assert d1['some_cookie'] == 'some_value'
         assert d2['some_cookie'] == 'some_value'
@@ -757,7 +755,7 @@ class TestRequests(object):
         jar.set(key, value)
         jar.set(key1, value1)
 
-        keys = jar.keys()
+        keys = list(jar.keys())
         assert keys == list(keys)
         # make sure one can use keys multiple times
         assert list(keys) == list(keys)
@@ -773,7 +771,7 @@ class TestRequests(object):
         jar.set(key, value)
         jar.set(key1, value1)
 
-        values = jar.values()
+        values = list(jar.values())
         assert values == list(values)
         # make sure one can use values multiple times
         assert list(values) == list(values)
@@ -789,7 +787,7 @@ class TestRequests(object):
         jar.set(key, value)
         jar.set(key1, value1)
 
-        items = jar.items()
+        items = list(jar.items())
         assert items == list(items)
         # make sure one can use items multiple times
         assert list(items) == list(items)
@@ -962,7 +960,7 @@ class TestRequests(object):
         assert r.json()['args'] == {'foo': 'bar', 'FOO': 'bar'}
 
     def test_long_authinfo_in_url(self):
-        url = 'http://{0}:{1}@{2}:9000/path?query#frag'.format(
+        url = 'http://{}:{}@{}:9000/path?query#frag'.format(
             'E8A3BE87-9E3F-4620-8858-95478E385B5B',
             'EA770032-DA4D-4D84-8CE9-29C6D910BF1E',
             'exactly-------------sixty-----------three------------characters',
@@ -971,14 +969,14 @@ class TestRequests(object):
         assert r.url == url
 
     def test_header_keys_are_native(self, httpbin):
-        headers = {u('unicode'): 'blah', 'byte'.encode('ascii'): 'blah'}
+        headers = {u('unicode'): 'blah', b'byte': 'blah'}
         r = requests.Request('GET', httpbin('get'), headers=headers)
         p = r.prepare()
 
         # This is testing that they are builtin strings. A bit weird, but there
         # we go.
-        assert 'unicode' in p.headers.keys()
-        assert 'byte' in p.headers.keys()
+        assert 'unicode' in list(p.headers.keys())
+        assert 'byte' in list(p.headers.keys())
 
     def test_can_send_nonstring_objects_with_files(self, httpbin):
         data = {'a': 0.0}
@@ -1306,7 +1304,7 @@ class TestCaseInsensitiveDict(unittest.TestCase):
         })
         keyset = frozenset(['Accept', 'user-Agent'])
         assert frozenset(i[0] for i in cid.items()) == keyset
-        assert frozenset(cid.keys()) == keyset
+        assert frozenset(list(cid.keys())) == keyset
         assert frozenset(cid) == keyset
 
     def test_preserve_last_key_case(self):
@@ -1318,7 +1316,7 @@ class TestCaseInsensitiveDict(unittest.TestCase):
         cid['USER-AGENT'] = 'requests'
         keyset = frozenset(['ACCEPT', 'USER-AGENT'])
         assert frozenset(i[0] for i in cid.items()) == keyset
-        assert frozenset(cid.keys()) == keyset
+        assert frozenset(list(cid.keys())) == keyset
         assert frozenset(cid) == keyset
 
     def test_copy(self):
@@ -1731,7 +1729,7 @@ def test_urllib3_pool_connection_closed(httpbin):
     try:
         s.get(httpbin('status/200'))
     except ConnectionError as e:
-        assert u"Pool is closed." in str(e)
+        assert "Pool is closed." in str(e)
 
 
 def test_vendor_aliases():
diff --git a/python/rsa/create_timing_table.py b/python/rsa/create_timing_table.py
index b1b2871b3d..b37f20ae52 100755
--- a/python/rsa/create_timing_table.py
+++ b/python/rsa/create_timing_table.py
@@ -20,7 +20,7 @@ def run_speed_test(bitsize):
     duration = end - start
     dur_per_call = duration / iterations
 
-    print '%5i bit: %9.3f sec. (%i iterations over %.1f seconds)' % (bitsize,
+    print('%5i bit: %9.3f sec. (%i iterations over %.1f seconds)' % (bitsize,)
             dur_per_call, iterations, duration)
 
 for bitsize in (128, 256, 384, 512, 1024, 2048, 3072, 4096):
diff --git a/python/rsa/rsa/__init__.py b/python/rsa/rsa/__init__.py
index 2d01c12e0f..305ccf56be 100644
--- a/python/rsa/rsa/__init__.py
+++ b/python/rsa/rsa/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
diff --git a/python/rsa/rsa/_compat.py b/python/rsa/rsa/_compat.py
index 3c4eb81b13..8dc522c3a5 100644
--- a/python/rsa/rsa/_compat.py
+++ b/python/rsa/rsa/_compat.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -17,7 +16,6 @@
 """Python compatibility wrappers."""
 
 
-from __future__ import absolute_import
 
 import sys
 from struct import pack
@@ -25,7 +23,7 @@ from struct import pack
 try:
     MAX_INT = sys.maxsize
 except AttributeError:
-    MAX_INT = sys.maxint
+    MAX_INT = sys.maxsize
 
 MAX_INT64 = (1 << 63) - 1
 MAX_INT32 = (1 << 31) - 1
@@ -45,7 +43,7 @@ else:
 
 try:
     # < Python3
-    unicode_type = unicode
+    unicode_type = str
     have_python3 = False
 except NameError:
     # Python3.
@@ -62,7 +60,7 @@ else:
 
 # ``long`` is no more. Do type detection using this instead.
 try:
-    integer_types = (int, long)
+    integer_types = int
 except NameError:
     integer_types = (int,)
 
diff --git a/python/rsa/rsa/_version133.py b/python/rsa/rsa/_version133.py
index 230a03c84b..65aa3ede92 100644
--- a/python/rsa/rsa/_version133.py
+++ b/python/rsa/rsa/_version133.py
@@ -18,7 +18,7 @@ __version__ = '1.3.3'
 # NOTE: Python's modulo can return negative numbers. We compensate for
 # this behaviour using the abs() function
 
-from cPickle import dumps, loads
+from six.moves.cPickle import dumps, loads
 import base64
 import math
 import os
@@ -55,14 +55,14 @@ def bytes2int(bytes):
     8405007
     """
 
-    if not (type(bytes) is types.ListType or type(bytes) is types.StringType):
+    if not (type(bytes) is list or type(bytes) is bytes):
         raise TypeError("You must pass a string or a list")
 
     # Convert byte stream to integer
     integer = 0
     for byte in bytes:
         integer *= 256
-        if type(byte) is types.StringType: byte = ord(byte)
+        if type(byte) is bytes: byte = ord(byte)
         integer += byte
 
     return integer
@@ -74,13 +74,13 @@ def int2bytes(number):
     123456789
     """
 
-    if not (type(number) is types.LongType or type(number) is types.IntType):
+    if not (type(number) is int or type(number) is int):
         raise TypeError("You must pass a long or an int")
 
     string = ""
 
     while number > 0:
-        string = "%s%s" % (byte(number & 0xFF), string)
+        string = "{}{}".format(byte(number & 0xFF), string)
         number /= 256
     
     return string
@@ -268,7 +268,7 @@ def extended_euclid_gcd(a, b):
         return (a, 1, 0)
 
     q = abs(a % b)
-    r = long(a / b)
+    r = int(a / b)
     (d, k, l) = extended_euclid_gcd(b, q)
 
     return (d, l, k - l*r)
@@ -330,10 +330,10 @@ def encrypt_int(message, ekey, n):
     """Encrypts a message using encryption key 'ekey', working modulo
     n"""
 
-    if type(message) is types.IntType:
-        return encrypt_int(long(message), ekey, n)
+    if type(message) is int:
+        return encrypt_int(int(message), ekey, n)
 
-    if not type(message) is types.LongType:
+    if not type(message) is int:
         raise TypeError("You must pass a long or an int")
 
     if message > 0 and \
diff --git a/python/rsa/rsa/_version200.py b/python/rsa/rsa/_version200.py
index f915653857..4b047c320e 100644
--- a/python/rsa/rsa/_version200.py
+++ b/python/rsa/rsa/_version200.py
@@ -52,14 +52,14 @@ def bytes2int(bytes):
     8405007
     """
 
-    if not (type(bytes) is types.ListType or type(bytes) is types.StringType):
+    if not (type(bytes) is list or type(bytes) is bytes):
         raise TypeError("You must pass a string or a list")
 
     # Convert byte stream to integer
     integer = 0
     for byte in bytes:
         integer *= 256
-        if type(byte) is types.StringType: byte = ord(byte)
+        if type(byte) is bytes: byte = ord(byte)
         integer += byte
 
     return integer
@@ -69,13 +69,13 @@ def int2bytes(number):
     Converts a number to a string of bytes
     """
 
-    if not (type(number) is types.LongType or type(number) is types.IntType):
+    if not (type(number) is int or type(number) is int):
         raise TypeError("You must pass a long or an int")
 
     string = ""
 
     while number > 0:
-        string = "%s%s" % (byte(number & 0xFF), string)
+        string = "{}{}".format(byte(number & 0xFF), string)
         number /= 256
     
     return string
@@ -88,7 +88,7 @@ def to64(number):
     'A'
     """
 
-    if not (type(number) is types.LongType or type(number) is types.IntType):
+    if not (type(number) is int or type(number) is int):
         raise TypeError("You must pass a long or an int")
 
     if 0 <= number <= 9:            #00-09 translates to '0' - '9'
@@ -117,7 +117,7 @@ def from64(number):
     1
     """
 
-    if not (type(number) is types.LongType or type(number) is types.IntType):
+    if not (type(number) is int or type(number) is int):
         raise TypeError("You must pass a long or an int")
 
     if 48 <= number <= 57:         #ord('0') - ord('9') translates to 0-9
@@ -146,13 +146,13 @@ def int2str64(number):
     '7MyqL'
     """
 
-    if not (type(number) is types.LongType or type(number) is types.IntType):
+    if not (type(number) is int or type(number) is int):
         raise TypeError("You must pass a long or an int")
 
     string = ""
 
     while number > 0:
-        string = "%s%s" % (to64(number & 0x3F), string)
+        string = "{}{}".format(to64(number & 0x3F), string)
         number /= 64
 
     return string
@@ -166,13 +166,13 @@ def str642int(string):
     123456789
     """
 
-    if not (type(string) is types.ListType or type(string) is types.StringType):
+    if not (type(string) is list or type(string) is bytes):
         raise TypeError("You must pass a string or a list")
 
     integer = 0
     for byte in string:
         integer *= 64
-        if type(byte) is types.StringType: byte = ord(byte)
+        if type(byte) is bytes: byte = ord(byte)
         integer += from64(byte)
 
     return integer
@@ -333,7 +333,7 @@ def extended_gcd(a, b):
     oa = a                             #Remember original a/b to remove 
     ob = b                             #negative values from return results
     while b != 0:
-        q = long(a/b)
+        q = int(a/b)
         (a, b)  = (b, a % b)
         (x, lx) = ((lx - (q * x)),x)
         (y, ly) = ((ly - (q * y)),y)
@@ -393,10 +393,10 @@ def newkeys(nbits):
 def encrypt_int(message, ekey, n):
     """Encrypts a message using encryption key 'ekey', working modulo n"""
 
-    if type(message) is types.IntType:
-        message = long(message)
+    if type(message) is int:
+        message = int(message)
 
-    if not type(message) is types.LongType:
+    if not type(message) is int:
         raise TypeError("You must pass a long or int")
 
     if message < 0 or message > n:
diff --git a/python/rsa/rsa/bigfile.py b/python/rsa/rsa/bigfile.py
index 516cf56b51..87a861581b 100644
--- a/python/rsa/rsa/bigfile.py
+++ b/python/rsa/rsa/bigfile.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
diff --git a/python/rsa/rsa/cli.py b/python/rsa/rsa/cli.py
index 527cc4979a..afff615ea1 100644
--- a/python/rsa/rsa/cli.py
+++ b/python/rsa/rsa/cli.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -19,7 +18,6 @@
 These scripts are called by the executables defined in setup.py.
 '''
 
-from __future__ import with_statement, print_function
 
 import abc
 import sys
@@ -87,7 +85,7 @@ def keygen():
         sys.stdout.write(data)
 
 
-class CryptoOperation(object):
+class CryptoOperation:
     '''CLI callable that operates with input, output, and a key.'''
 
     __metaclass__ = abc.ABCMeta
@@ -164,7 +162,7 @@ class CryptoOperation(object):
     def read_key(self, filename, keyform):
         '''Reads a public or private key.'''
 
-        print('Reading %s key from %s' % (self.keyname, filename), file=sys.stderr)
+        print('Reading {} key from {}'.format(self.keyname, filename), file=sys.stderr)
         with open(filename, 'rb') as keyfile:
             keydata = keyfile.read()
 
diff --git a/python/rsa/rsa/common.py b/python/rsa/rsa/common.py
index 39feb8c228..216259f7f4 100644
--- a/python/rsa/rsa/common.py
+++ b/python/rsa/rsa/common.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
diff --git a/python/rsa/rsa/core.py b/python/rsa/rsa/core.py
index 90dfee8e57..a1a4786b1a 100644
--- a/python/rsa/rsa/core.py
+++ b/python/rsa/rsa/core.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -28,7 +27,7 @@ def assert_int(var, name):
     if is_integer(var):
         return
 
-    raise TypeError('%s should be an integer, not %s' % (name, var.__class__))
+    raise TypeError('{} should be an integer, not {}'.format(name, var.__class__))
 
 def encrypt_int(message, ekey, n):
     '''Encrypts a message using encryption key 'ekey', working modulo n'''
diff --git a/python/rsa/rsa/key.py b/python/rsa/rsa/key.py
index b6de7b3f3b..0615f392e8 100644
--- a/python/rsa/rsa/key.py
+++ b/python/rsa/rsa/key.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -25,6 +24,7 @@ of pyasn1.
 
 '''
 
+from __future__ import print_function
 import logging
 from rsa._compat import b, bytes_type
 
@@ -36,7 +36,7 @@ log = logging.getLogger(__name__)
 
 
 
-class AbstractKey(object):
+class AbstractKey:
     '''Abstract superclass for private and public keys.'''
 
     @classmethod
@@ -58,7 +58,7 @@ class AbstractKey(object):
 
         if format not in methods:
             formats = ', '.join(sorted(methods.keys()))
-            raise ValueError('Unsupported format: %r, try one of %s' % (format,
+            raise ValueError('Unsupported format: {!r}, try one of {}'.format(format,
                 formats))
 
         method = methods[format]
@@ -79,7 +79,7 @@ class AbstractKey(object):
 
         if format not in methods:
             formats = ', '.join(sorted(methods.keys()))
-            raise ValueError('Unsupported format: %r, try one of %s' % (format,
+            raise ValueError('Unsupported format: {!r}, try one of {}'.format(format,
                 formats))
 
         method = methods[format]
@@ -605,7 +605,7 @@ if __name__ == '__main__':
                 break
 
             if (count and count % 10 == 0) or count == 1:
-                print('%i times' % count)
+                print(('%i times' % count))
     except KeyboardInterrupt:
         print('Aborted')
     else:
diff --git a/python/rsa/rsa/parallel.py b/python/rsa/rsa/parallel.py
index e5034ac707..a170358461 100644
--- a/python/rsa/rsa/parallel.py
+++ b/python/rsa/rsa/parallel.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -24,8 +23,8 @@ Introduced in Python-RSA 3.1.
 
 '''
 
-from __future__ import print_function
 
+from __future__ import print_function
 import multiprocessing as mp
 
 import rsa.prime
@@ -88,7 +87,7 @@ if __name__ == '__main__':
             break
         
         if count and count % 10 == 0:
-            print('%i times' % count)
+            print(('%i times' % count))
     
     print('Doctests done')
 
diff --git a/python/rsa/rsa/pem.py b/python/rsa/rsa/pem.py
index b1c3a0edb4..d47534619a 100644
--- a/python/rsa/rsa/pem.py
+++ b/python/rsa/rsa/pem.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
diff --git a/python/rsa/rsa/pkcs1.py b/python/rsa/rsa/pkcs1.py
index 15e4cf639e..5dc33d87d4 100644
--- a/python/rsa/rsa/pkcs1.py
+++ b/python/rsa/rsa/pkcs1.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -28,6 +27,7 @@ can be used to deduce where in the process the failure occurred. DO NOT PASS
 SUCH INFORMATION to your users.
 '''
 
+from __future__ import print_function
 import hashlib
 import os
 
@@ -386,6 +386,6 @@ if __name__ == '__main__':
             break
         
         if count and count % 100 == 0:
-            print('%i times' % count)
+            print(('%i times' % count))
     
     print('Doctests done')
diff --git a/python/rsa/rsa/prime.py b/python/rsa/rsa/prime.py
index 7422eb1d28..574d413bae 100644
--- a/python/rsa/rsa/prime.py
+++ b/python/rsa/rsa/prime.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -20,6 +19,7 @@ Implementation based on the book Algorithm Design by Michael T. Goodrich and
 Roberto Tamassia, 2002.
 '''
 
+from __future__ import print_function
 __all__ = [ 'getprime', 'are_relatively_prime']
 
 import rsa.randnum
@@ -161,6 +161,6 @@ if __name__ == '__main__':
             break
         
         if count and count % 100 == 0:
-            print('%i times' % count)
+            print(('%i times' % count))
     
     print('Doctests done')
diff --git a/python/rsa/rsa/randnum.py b/python/rsa/rsa/randnum.py
index 0e782744c0..16c2bdaafd 100644
--- a/python/rsa/rsa/randnum.py
+++ b/python/rsa/rsa/randnum.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
diff --git a/python/rsa/rsa/transform.py b/python/rsa/rsa/transform.py
index c740b2d275..ebdca1f1d9 100644
--- a/python/rsa/rsa/transform.py
+++ b/python/rsa/rsa/transform.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -19,7 +18,6 @@
 From bytes to a number, number to bytes, etc.
 '''
 
-from __future__ import absolute_import
 
 try:
     # We'll use psyco if available on 32-bit architectures to speed up code.
diff --git a/python/rsa/rsa/util.py b/python/rsa/rsa/util.py
index 5bbb70be18..5c34c57ee2 100644
--- a/python/rsa/rsa/util.py
+++ b/python/rsa/rsa/util.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
@@ -16,7 +15,6 @@
 
 '''Utility functions.'''
 
-from __future__ import with_statement, print_function
 
 import sys
 from optparse import OptionParser
diff --git a/python/rsa/rsa/varblock.py b/python/rsa/rsa/varblock.py
index c7d96ae6a7..563873a48a 100644
--- a/python/rsa/rsa/varblock.py
+++ b/python/rsa/rsa/varblock.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 #  Copyright 2011 Sybren A. Stüvel 
 #
diff --git a/python/rsa/run_tests.py b/python/rsa/run_tests.py
index e0f249081f..577c95a495 100644
--- a/python/rsa/run_tests.py
+++ b/python/rsa/run_tests.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 import os
 import sys
diff --git a/python/rsa/tests/constants.py b/python/rsa/tests/constants.py
index 6a0d081836..7159fd66f9 100644
--- a/python/rsa/tests/constants.py
+++ b/python/rsa/tests/constants.py
@@ -1,9 +1,7 @@
-# -*- coding: utf-8 -*-
-
 from rsa._compat import have_python3
 
 if have_python3:
-    from py3kconstants import *
+    from .py3kconstants import *
 else:
-    from py2kconstants import *
+    from .py2kconstants import *
 
diff --git a/python/rsa/tests/py2kconstants.py b/python/rsa/tests/py2kconstants.py
index 5f695dd227..9c52637d2a 100644
--- a/python/rsa/tests/py2kconstants.py
+++ b/python/rsa/tests/py2kconstants.py
@@ -1,3 +1 @@
-# -*- coding: utf-8 -*-
-
-unicode_string = u"Euro=\u20ac ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+unicode_string = "Euro=\u20ac ABCDEFGHIJKLMNOPQRSTUVWXYZ"
diff --git a/python/rsa/tests/py3kconstants.py b/python/rsa/tests/py3kconstants.py
index 83b67129c9..9c52637d2a 100644
--- a/python/rsa/tests/py3kconstants.py
+++ b/python/rsa/tests/py3kconstants.py
@@ -1,3 +1 @@
-# -*- coding: utf-8 -*-
-
 unicode_string = "Euro=\u20ac ABCDEFGHIJKLMNOPQRSTUVWXYZ"
diff --git a/python/rsa/tests/test_bigfile.py b/python/rsa/tests/test_bigfile.py
index 86bcbbac6f..a09bf83976 100644
--- a/python/rsa/tests/test_bigfile.py
+++ b/python/rsa/tests/test_bigfile.py
@@ -31,7 +31,7 @@ class BigfileTest(unittest2.TestCase):
         clearfile = BytesIO()
 
         bigfile.decrypt_bigfile(cryptfile, clearfile, priv_key)
-        self.assertEquals(clearfile.getvalue(), message)
+        self.assertEqual(clearfile.getvalue(), message)
         
         # We have 2x6 bytes in the message, so that should result in two
         # bigfile.
diff --git a/python/rsa/tests/test_common.py b/python/rsa/tests/test_common.py
index d105dc020f..00d871b012 100644
--- a/python/rsa/tests/test_common.py
+++ b/python/rsa/tests/test_common.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 import unittest2
 import struct
diff --git a/python/rsa/tests/test_compat.py b/python/rsa/tests/test_compat.py
index 3652c82d51..cfa2c2b2d1 100644
--- a/python/rsa/tests/test_compat.py
+++ b/python/rsa/tests/test_compat.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 import unittest2
 import struct
 
diff --git a/python/rsa/tests/test_integers.py b/python/rsa/tests/test_integers.py
index 0a712aa0fc..8f75829779 100644
--- a/python/rsa/tests/test_integers.py
+++ b/python/rsa/tests/test_integers.py
@@ -1,5 +1,6 @@
 '''Tests integer operations.'''
 
+from __future__ import print_function
 import unittest2
 
 import rsa.core
@@ -12,13 +13,13 @@ class IntegerTest(unittest2.TestCase):
     def test_enc_dec(self):
 
         message = 42
-        print("\tMessage:   %d" % message)
+        print(("\tMessage:   %d" % message))
 
         encrypted = rsa.core.encrypt_int(message, self.pub.e, self.pub.n)
-        print("\tEncrypted: %d" % encrypted)
+        print(("\tEncrypted: %d" % encrypted))
 
         decrypted = rsa.core.decrypt_int(encrypted, self.priv.d, self.pub.n)
-        print("\tDecrypted: %d" % decrypted)
+        print(("\tDecrypted: %d" % decrypted))
 
         self.assertEqual(message, decrypted)
 
@@ -27,10 +28,10 @@ class IntegerTest(unittest2.TestCase):
         message = 42
 
         signed = rsa.core.encrypt_int(message,self.priv.d, self.pub.n)
-        print("\tSigned:    %d" % signed)
+        print(("\tSigned:    %d" % signed))
 
         verified = rsa.core.decrypt_int(signed, self.pub.e,self.pub.n)
-        print("\tVerified:  %d" % verified)
+        print(("\tVerified:  %d" % verified))
 
         self.assertEqual(message, verified)
 
diff --git a/python/rsa/tests/test_pem.py b/python/rsa/tests/test_pem.py
index 867f678a0e..acfd3670b4 100644
--- a/python/rsa/tests/test_pem.py
+++ b/python/rsa/tests/test_pem.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 
 import unittest2
diff --git a/python/rsa/tests/test_pkcs1.py b/python/rsa/tests/test_pkcs1.py
index d5882dfd1b..dea45c85c2 100644
--- a/python/rsa/tests/test_pkcs1.py
+++ b/python/rsa/tests/test_pkcs1.py
@@ -1,5 +1,6 @@
 '''Tests string operations.'''
 
+from __future__ import print_function
 import struct
 import unittest2
 
@@ -15,13 +16,13 @@ class BinaryTest(unittest2.TestCase):
     def test_enc_dec(self):
 
         message = struct.pack('>IIII', 0, 0, 0, 1)
-        print("\tMessage:   %r" % message)
+        print(("\tMessage:   %r" % message))
 
         encrypted = pkcs1.encrypt(message, self.pub)
-        print("\tEncrypted: %r" % encrypted)
+        print(("\tEncrypted: %r" % encrypted))
 
         decrypted = pkcs1.decrypt(encrypted, self.priv)
-        print("\tDecrypted: %r" % decrypted)
+        print(("\tDecrypted: %r" % decrypted))
 
         self.assertEqual(message, decrypted)
 
@@ -59,10 +60,10 @@ class SignatureTest(unittest2.TestCase):
         '''Test happy flow of sign and verify'''
         
         message = b('je moeder')
-        print("\tMessage:   %r" % message)
+        print(("\tMessage:   %r" % message))
 
         signature = pkcs1.sign(message, self.priv, 'SHA-256')
-        print("\tSignature: %r" % signature)
+        print(("\tSignature: %r" % signature))
 
         self.assertTrue(pkcs1.verify(message, signature, self.pub))
 
diff --git a/python/rsa/tests/test_strings.py b/python/rsa/tests/test_strings.py
index 4af06291d4..2762dd3d9f 100644
--- a/python/rsa/tests/test_strings.py
+++ b/python/rsa/tests/test_strings.py
@@ -1,12 +1,12 @@
 '''Tests string operations.'''
 
-from __future__ import absolute_import
 
+from __future__ import print_function
 import unittest2
 
 import rsa
 
-from constants import unicode_string
+from .constants import unicode_string
 
 class StringTest(unittest2.TestCase):
 
@@ -16,13 +16,13 @@ class StringTest(unittest2.TestCase):
     def test_enc_dec(self):
 
         message = unicode_string.encode('utf-8')
-        print("\tMessage:   %s" % message)
+        print(("\tMessage:   %s" % message))
 
         encrypted = rsa.encrypt(message, self.pub)
-        print("\tEncrypted: %s" % encrypted)
+        print(("\tEncrypted: %s" % encrypted))
 
         decrypted = rsa.decrypt(encrypted, self.priv)
-        print("\tDecrypted: %s" % decrypted)
+        print(("\tDecrypted: %s" % decrypted))
 
         self.assertEqual(message, decrypted)
 
diff --git a/python/rsa/tests/test_transform.py b/python/rsa/tests/test_transform.py
index ffd9ec892a..392e824774 100644
--- a/python/rsa/tests/test_transform.py
+++ b/python/rsa/tests/test_transform.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-
-
 import unittest2
 from rsa._compat import b
 from rsa.transform import int2bytes, bytes2int, _int2bytes
diff --git a/python/slugid/setup.py b/python/slugid/setup.py
index d7c8b328bd..229849952b 100644
--- a/python/slugid/setup.py
+++ b/python/slugid/setup.py
@@ -14,7 +14,7 @@ packages = [
 ]
 
 version = ''
-with open('slugid/__init__.py', 'r') as fd:
+with open('slugid/__init__.py') as fd:
     version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
                         fd.read(), re.MULTILINE).group(1)
 
diff --git a/python/slugid/slugid/__init__.py b/python/slugid/slugid/__init__.py
index ca7de07e24..4d5b75b906 100644
--- a/python/slugid/slugid/__init__.py
+++ b/python/slugid/slugid/__init__.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 #    **************
 #    * Slugid API *
 #    **************
diff --git a/python/virtualenv/bin/rebuild-script.py b/python/virtualenv/bin/rebuild-script.py
index a816af3eb7..81b654ec79 100755
--- a/python/virtualenv/bin/rebuild-script.py
+++ b/python/virtualenv/bin/rebuild-script.py
@@ -2,7 +2,6 @@
 """
 Helper script to rebuild virtualenv.py from virtualenv_support
 """
-from __future__ import print_function
 
 import os
 import re
diff --git a/python/virtualenv/docs/conf.py b/python/virtualenv/docs/conf.py
index 9332aa1bc7..33920cf0d3 100644
--- a/python/virtualenv/docs/conf.py
+++ b/python/virtualenv/docs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 # Paste documentation build configuration file, created by
 # sphinx-quickstart on Tue Apr 22 22:08:49 2008.
diff --git a/python/virtualenv/setup.py b/python/virtualenv/setup.py
index ee03bc5313..9d738d6b62 100644
--- a/python/virtualenv/setup.py
+++ b/python/virtualenv/setup.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import os
 import re
 import shutil
diff --git a/python/virtualenv/site.py b/python/virtualenv/site.py
index bf23c19204..75a16b47a1 100644
--- a/python/virtualenv/site.py
+++ b/python/virtualenv/site.py
@@ -63,12 +63,13 @@ ImportError exception, it is silently ignored.
 
 """
 
+from __future__ import print_function
 import sys
 import os
 import platform
 
 try:
-    import __builtin__ as builtins
+    import builtins as builtins
 except ImportError:
     import builtins
 try:
@@ -139,7 +140,7 @@ def addbuilddir():
     """Append ./build/lib. in case we're running in the build dir
     (especially for Guido :-)"""
     from distutils.util import get_platform
-    s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
+    s = "build/lib.{}-{:.3}".format(get_platform(), sys.version)
     if hasattr(sys, 'gettotalrefcount'):
         s += '-pydebug'
     s = os.path.join(os.path.dirname(sys.path[-1]), s)
@@ -167,8 +168,8 @@ def addpackage(sitedir, name, known_paths):
         reset = 0
     fullname = os.path.join(sitedir, name)
     try:
-        f = open(fullname, "rU")
-    except IOError:
+        f = open(fullname)
+    except OSError:
         return
     try:
         for line in f:
@@ -201,7 +202,7 @@ def addsitedir(sitedir, known_paths=None):
         sys.path.append(sitedir)        # Add path component
     try:
         names = os.listdir(sitedir)
-    except os.error:
+    except OSError:
         return
     names.sort()
     for name in names:
@@ -393,11 +394,11 @@ def setquit():
     else:
         eof = 'Ctrl-D (i.e. EOF)'
 
-    class Quitter(object):
+    class Quitter:
         def __init__(self, name):
             self.name = name
         def __repr__(self):
-            return 'Use %s() or %s to exit' % (self.name, eof)
+            return 'Use {}() or {} to exit'.format(self.name, eof)
         def __call__(self, code=None):
             # Shells like IDLE catch the SystemExit, but listen when their
             # stdin wrapper is closed.
@@ -410,7 +411,7 @@ def setquit():
     builtins.exit = Quitter('exit')
 
 
-class _Printer(object):
+class _Printer:
     """interactive prompt objects for printing the license text, a list of
     contributors and the copyright notice."""
 
@@ -431,11 +432,11 @@ class _Printer(object):
             for filename in self.__files:
                 filename = os.path.join(dir, filename)
                 try:
-                    fp = open(filename, "rU")
+                    fp = open(filename)
                     data = fp.read()
                     fp.close()
                     break
-                except IOError:
+                except OSError:
                     pass
             if data:
                 break
@@ -458,7 +459,7 @@ class _Printer(object):
         while 1:
             try:
                 for i in range(lineno, lineno + self.MAXLINES):
-                    print(self.__lines[i])
+                    print((self.__lines[i]))
             except IndexError:
                 break
             else:
@@ -466,9 +467,9 @@ class _Printer(object):
                 key = None
                 while key is None:
                     try:
-                        key = raw_input(prompt)
-                    except NameError:
                         key = input(prompt)
+                    except NameError:
+                        key = eval(input(prompt))
                     if key not in ('', 'q'):
                         key = None
                 if key == 'q':
@@ -496,7 +497,7 @@ def setcopyright():
         [os.path.join(here, os.pardir), here, os.curdir])
 
 
-class _Helper(object):
+class _Helper:
     """Define the built-in 'help'.
     This is a wrapper around pydoc.help (with a twist).
 
@@ -727,16 +728,16 @@ def _script():
     if not args:
         print("sys.path = [")
         for dir in sys.path:
-            print("    %r," % (dir,))
+            print(("    {!r},".format(dir)))
         print("]")
         def exists(path):
             if os.path.isdir(path):
                 return "exists"
             else:
                 return "doesn't exist"
-        print("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE)))
-        print("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE)))
-        print("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE)
+        print(("USER_BASE: {!r} ({})".format(USER_BASE, exists(USER_BASE))))
+        print(("USER_SITE: {!r} ({})".format(USER_SITE, exists(USER_BASE))))
+        print(("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE))
         sys.exit(0)
 
     buffer = []
@@ -746,7 +747,7 @@ def _script():
         buffer.append(USER_SITE)
 
     if buffer:
-        print(os.pathsep.join(buffer))
+        print((os.pathsep.join(buffer)))
         if ENABLE_USER_SITE:
             sys.exit(0)
         elif ENABLE_USER_SITE is False:
@@ -757,7 +758,7 @@ def _script():
             sys.exit(3)
     else:
         import textwrap
-        print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
+        print((textwrap.dedent(help % (sys.argv[0], os.pathsep))))
         sys.exit(10)
 
 if __name__ == '__main__':
diff --git a/python/virtualenv/tests/test_virtualenv.py b/python/virtualenv/tests/test_virtualenv.py
index 756cde9368..57fecf005c 100644
--- a/python/virtualenv/tests/test_virtualenv.py
+++ b/python/virtualenv/tests/test_virtualenv.py
@@ -7,7 +7,7 @@ import tempfile
 import pytest
 import platform  # noqa
 
-from mock import patch, Mock
+from unittest.mock import patch, Mock
 
 
 def test_version():
@@ -110,7 +110,7 @@ def test_install_python_bin():
         else:
             py_exe_no_version = 'python'
             py_exe_version_major = 'python%s' % sys.version_info[0]
-            py_exe_version_major_minor = 'python%s.%s' % (
+            py_exe_version_major_minor = 'python{}.{}'.format(
                 sys.version_info[0], sys.version_info[1])
             required_executables = [ py_exe_no_version, py_exe_version_major,
                                      py_exe_version_major_minor ]
diff --git a/python/virtualenv/virtualenv.py b/python/virtualenv/virtualenv.py
index 60a42e4dcb..f67a642305 100755
--- a/python/virtualenv/virtualenv.py
+++ b/python/virtualenv/virtualenv.py
@@ -1,8 +1,10 @@
 #!/usr/bin/env python
 """Create a "virtual" Python installation"""
 
+from __future__ import print_function
 import os
 import sys
+import six
 
 # If we are running in a new interpreter to create a virtualenv,
 # we do NOT want paths from our existing location interfering with anything,
@@ -32,7 +34,7 @@ from distutils.util import strtobool
 from os.path import join
 
 try:
-    import ConfigParser
+    import six.moves.configparser
 except ImportError:
     import configparser as ConfigParser
 
@@ -40,16 +42,16 @@ __version__ = "15.0.1"
 virtualenv_version = __version__  # legacy
 
 if sys.version_info < (2, 6):
-    print('ERROR: %s' % sys.exc_info()[1])
+    print(('ERROR: %s' % sys.exc_info()[1]))
     print('ERROR: this script requires Python 2.6 or greater.')
     sys.exit(101)
 
 import platform
 
 try:
-    basestring
+    str
 except NameError:
-    basestring = str
+    str = str
 
 is_tauthon = platform.python_implementation() == "Tauthon"
 is_jython = sys.platform.startswith('java')
@@ -60,7 +62,7 @@ is_msys2 = (sys.platform == 'win32' and os.sep == '/')
 is_darwin = (sys.platform == 'darwin')
 abiflags = getattr(sys, 'abiflags', '')
 
-py_version = '%s%s.%s' % ("tauthon" if is_tauthon else "python",
+py_version = '{}{}.{}'.format("tauthon" if is_tauthon else "python",
                           sys.version_info[0], sys.version_info[1])
 
 user_dir = os.path.expanduser('~')
@@ -86,13 +88,13 @@ else:
     try:
         import winreg
     except ImportError:
-        import _winreg as winreg
+        import six.moves.winreg as winreg
 
     def get_installed_pythons():
         try:
             python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE,
                                            "Software\\Python\\PythonCore")
-        except WindowsError:
+        except OSError:
             # No registered Python installations
             return {}
         i = 0
@@ -101,13 +103,13 @@ else:
             try:
                 versions.append(winreg.EnumKey(python_core, i))
                 i = i + 1
-            except WindowsError:
+            except OSError:
                 break
         exes = dict()
         for ver in versions:
             try:
                 path = winreg.QueryValue(python_core, "%s\\InstallPath" % ver)
-            except WindowsError:
+            except OSError:
                 continue
             exes[ver] = join(path, "python.exe")
 
@@ -171,7 +173,7 @@ if is_pypy:
     REQUIRED_MODULES.extend(['traceback', 'linecache'])
 
 
-class Logger(object):
+class Logger:
 
     """
     Logging object for use in command-line script.  Allows ranges of
@@ -433,7 +435,7 @@ class ConfigOptionParser(optparse.OptionParser):
     configuration files and environmental variables
     """
     def __init__(self, *args, **kwargs):
-        self.config = ConfigParser.RawConfigParser()
+        self.config = six.moves.configparser.RawConfigParser()
         self.files = self.get_config_files()
         self.config.read(self.files)
         optparse.OptionParser.__init__(self, *args, **kwargs)
@@ -479,7 +481,7 @@ class ConfigOptionParser(optparse.OptionParser):
                     val = option.convert_value(key, val)
                 except optparse.OptionValueError:
                     e = sys.exc_info()[1]
-                    print("An error occurred during configuration: %s" % e)
+                    print(("An error occurred during configuration: %s" % e))
                     sys.exit(3)
                 defaults[option.dest] = val
         return defaults
@@ -512,7 +514,7 @@ class ConfigOptionParser(optparse.OptionParser):
         defaults = self.update_defaults(self.defaults.copy())  # ours
         for option in self._get_all_options():
             default = defaults.get(option.dest)
-            if isinstance(default, basestring):
+            if isinstance(default, str):
                 opt_str = option.get_opt_string()
                 defaults[option.dest] = option.check_value(opt_str, default)
         return optparse.Values(defaults)
@@ -679,8 +681,8 @@ def main():
         parser.print_help()
         sys.exit(2)
     if len(args) > 1:
-        print('There must be only one argument: DEST_DIR (you gave %s)' % (
-            ' '.join(args)))
+        print(('There must be only one argument: DEST_DIR (you gave %s)' % (
+            ' '.join(args))))
         parser.print_help()
         sys.exit(2)
 
@@ -758,7 +760,7 @@ def call_subprocess(cmd, show_stdout=True,
     except Exception:
         e = sys.exc_info()[1]
         logger.fatal(
-            "Error %s while executing command %s" % (e, cmd_desc))
+            "Error {} while executing command {}".format(e, cmd_desc))
         raise
     all_output = []
     if stdout is not None:
@@ -831,7 +833,7 @@ def find_wheels(projects, search_dirs):
                 break
         else:
             # We're out of luck, so quit with a suitable error
-            logger.fatal('Cannot find a wheel for %s' % (project,))
+            logger.fatal('Cannot find a wheel for {}'.format(project))
 
     return wheels
 
@@ -846,8 +848,8 @@ def install_wheel(project_names, py_executable, search_dirs=None,
     # PIP_FIND_LINKS uses space as the path separator and thus cannot have paths
     # with spaces in them. Convert any of those to local file:// URL form.
     try:
-        from urlparse import urljoin
-        from urllib import pathname2url
+        from urllib.parse import urljoin
+        from urllib.request import pathname2url
     except ImportError:
         from urllib.parse import urljoin
         from urllib.request import pathname2url
@@ -974,12 +976,12 @@ def path_locations(home_dir):
             size = max(len(home_dir)+1, 256)
             buf = ctypes.create_unicode_buffer(size)
             try:
-                u = unicode
+                u = str
             except NameError:
                 u = str
             ret = GetShortPathName(u(home_dir), buf, size)
             if not ret:
-                print('Error: the path "%s" has a space in it' % home_dir)
+                print(('Error: the path "%s" has a space in it' % home_dir))
                 print('We could not determine the short pathname for it.')
                 print('Exiting.')
                 sys.exit(3)
@@ -1243,9 +1245,9 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy
                 os.unlink(python_d_dest)
             # we need to copy the DLL to enforce that windows will load the correct one.
             # may not exist if we are cygwin.
-            py_executable_dll = 'python%s%s.dll' % (
+            py_executable_dll = 'python{}{}.dll'.format(
                 sys.version_info[0], sys.version_info[1])
-            py_executable_dll_d = 'python%s%s_d.dll' % (
+            py_executable_dll_d = 'python{}{}_d.dll'.format(
                 sys.version_info[0], sys.version_info[1])
             pythondll = os.path.join(os.path.dirname(sys.executable), py_executable_dll)
             pythondll_d = os.path.join(os.path.dirname(sys.executable), py_executable_dll_d)
@@ -1351,7 +1353,7 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy
     if not is_win:
         # Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
         py_exe_version_major = 'python%s' % sys.version_info[0]
-        py_exe_version_major_minor = 'python%s.%s' % (
+        py_exe_version_major_minor = 'python{}.{}'.format(
             sys.version_info[0], sys.version_info[1])
         py_exe_no_version = 'python'
         required_symlinks = [ py_exe_no_version, py_exe_version_major,
@@ -1388,7 +1390,7 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy
     except OSError:
         e = sys.exc_info()[1]
         if e.errno == errno.EACCES:
-            logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
+            logger.fatal('ERROR: The executable {} could not be run: {}'.format(py_executable, e))
             sys.exit(100)
         else:
             raise e
@@ -1529,7 +1531,7 @@ def fix_lib64(lib_dir, symlink=True):
         return
     # Check we have a lib64 library path
     if not [p for p in distutils.sysconfig.get_config_vars().values()
-            if isinstance(p, basestring) and 'lib64' in p]:
+            if isinstance(p, str) and 'lib64' in p]:
         return
 
     logger.debug('This system uses lib64; symlinking lib64 to lib')
@@ -1566,10 +1568,10 @@ def resolve_interpreter(exe):
                 exe = join(path, exe)
                 break
     if not os.path.exists(exe):
-        logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
+        logger.fatal('The executable {} (from --python={}) does not exist'.format(exe, exe))
         raise SystemExit(3)
     if not is_executable(exe):
-        logger.fatal('The executable %s (from --python=%s) is not executable' % (exe, exe))
+        logger.fatal('The executable {} (from --python={}) is not executable'.format(exe, exe))
         raise SystemExit(3)
     return exe
 
@@ -1703,7 +1705,7 @@ def fixup_pth_file(filename):
         else:
             new_value = make_relative_path(filename, line)
             if line != new_value:
-                logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
+                logger.debug('Rewriting path {} as {} (in {})'.format(line, new_value, filename))
             lines.append(new_value)
     if lines == prev_lines:
         logger.info('No changes to .pth file %s' % filename)
@@ -1719,7 +1721,7 @@ def fixup_egg_link(filename):
         logger.debug('Link in %s already relative' % filename)
         return
     new_link = make_relative_path(filename, link)
-    logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
+    logger.notify('Rewriting link {} in {} as {}'.format(link, filename, new_link))
     with open(filename, 'w') as f:
         f.write(new_link)
 
@@ -2200,7 +2202,7 @@ LC_LOAD_DYLIB = 0xc
 maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint')
 
 
-class fileview(object):
+class fileview:
     """
     A proxy for file-like objects that exposes a given view of a file.
     Modified from macholib.
@@ -2224,7 +2226,7 @@ class fileview(object):
 
     def _checkwindow(self, seekto, op):
         if not (self._start <= seekto <= self._end):
-            raise IOError("%s to offset %d is outside window [%d, %d]" % (
+            raise OSError("%s to offset %d is outside window [%d, %d]" % (
                 op, seekto, self._start, self._end))
 
     def seek(self, offset, whence=0):
@@ -2236,7 +2238,7 @@ class fileview(object):
         elif whence == os.SEEK_END:
             seekto += self._end
         else:
-            raise IOError("Invalid whence argument to seek: %r" % (whence,))
+            raise OSError("Invalid whence argument to seek: {!r}".format(whence))
         self._checkwindow(seekto, 'seek')
         self._fileobj.seek(seekto)
         self._pos = seekto - self._start
@@ -2300,7 +2302,7 @@ def mach_o_change(path, what, value):
                 # If the string is what is being replaced, overwrite it.
                 if load == what:
                     file.seek(where + name_offset, os.SEEK_SET)
-                    file.write(value.encode() + '\0'.encode())
+                    file.write(value.encode() + b'\0')
             # Seek to the next command
             file.seek(where + cmdsize, os.SEEK_SET)
 
diff --git a/python/virtualenv/virtualenv_embedded/distutils-init.py b/python/virtualenv/virtualenv_embedded/distutils-init.py
index 29fc1da459..fe392b712b 100644
--- a/python/virtualenv/virtualenv_embedded/distutils-init.py
+++ b/python/virtualenv/virtualenv_embedded/distutils-init.py
@@ -25,9 +25,9 @@ else:
 from distutils import dist, sysconfig
 
 try:
-    basestring
+    str
 except NameError:
-    basestring = str
+    str = str
 
 ## patch build_ext (distutils doesn't know how to get the libs directory
 ## path on windows - it hardcodes the paths around the patched sys.prefix)
@@ -38,7 +38,7 @@ if sys.platform == 'win32':
         def finalize_options (self):
             if self.library_dirs is None:
                 self.library_dirs = []
-            elif isinstance(self.library_dirs, basestring):
+            elif isinstance(self.library_dirs, str):
                 self.library_dirs = self.library_dirs.split(os.pathsep)
             
             self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs"))
diff --git a/python/virtualenv/virtualenv_embedded/site.py b/python/virtualenv/virtualenv_embedded/site.py
index 7969769c36..abf7dce9ca 100644
--- a/python/virtualenv/virtualenv_embedded/site.py
+++ b/python/virtualenv/virtualenv_embedded/site.py
@@ -63,10 +63,11 @@ ImportError exception, it is silently ignored.
 
 """
 
+from __future__ import print_function
 import sys
 import os
 try:
-    import __builtin__ as builtins
+    import builtins as builtins
 except ImportError:
     import builtins
 try:
@@ -134,7 +135,7 @@ def addbuilddir():
     """Append ./build/lib. in case we're running in the build dir
     (especially for Guido :-)"""
     from distutils.util import get_platform
-    s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
+    s = "build/lib.{}-{:.3}".format(get_platform(), sys.version)
     if hasattr(sys, 'gettotalrefcount'):
         s += '-pydebug'
     s = os.path.join(os.path.dirname(sys.path[-1]), s)
@@ -162,8 +163,8 @@ def addpackage(sitedir, name, known_paths):
         reset = 0
     fullname = os.path.join(sitedir, name)
     try:
-        f = open(fullname, "rU")
-    except IOError:
+        f = open(fullname)
+    except OSError:
         return
     try:
         for line in f:
@@ -196,7 +197,7 @@ def addsitedir(sitedir, known_paths=None):
         sys.path.append(sitedir)        # Add path component
     try:
         names = os.listdir(sitedir)
-    except os.error:
+    except OSError:
         return
     names.sort()
     for name in names:
@@ -388,11 +389,11 @@ def setquit():
     else:
         eof = 'Ctrl-D (i.e. EOF)'
 
-    class Quitter(object):
+    class Quitter:
         def __init__(self, name):
             self.name = name
         def __repr__(self):
-            return 'Use %s() or %s to exit' % (self.name, eof)
+            return 'Use {}() or {} to exit'.format(self.name, eof)
         def __call__(self, code=None):
             # Shells like IDLE catch the SystemExit, but listen when their
             # stdin wrapper is closed.
@@ -405,7 +406,7 @@ def setquit():
     builtins.exit = Quitter('exit')
 
 
-class _Printer(object):
+class _Printer:
     """interactive prompt objects for printing the license text, a list of
     contributors and the copyright notice."""
 
@@ -426,11 +427,11 @@ class _Printer(object):
             for filename in self.__files:
                 filename = os.path.join(dir, filename)
                 try:
-                    fp = open(filename, "rU")
+                    fp = open(filename)
                     data = fp.read()
                     fp.close()
                     break
-                except IOError:
+                except OSError:
                     pass
             if data:
                 break
@@ -453,7 +454,7 @@ class _Printer(object):
         while 1:
             try:
                 for i in range(lineno, lineno + self.MAXLINES):
-                    print(self.__lines[i])
+                    print((self.__lines[i]))
             except IndexError:
                 break
             else:
@@ -461,9 +462,9 @@ class _Printer(object):
                 key = None
                 while key is None:
                     try:
-                        key = raw_input(prompt)
-                    except NameError:
                         key = input(prompt)
+                    except NameError:
+                        key = eval(input(prompt))
                     if key not in ('', 'q'):
                         key = None
                 if key == 'q':
@@ -491,7 +492,7 @@ def setcopyright():
         [os.path.join(here, os.pardir), here, os.curdir])
 
 
-class _Helper(object):
+class _Helper:
     """Define the built-in 'help'.
     This is a wrapper around pydoc.help (with a twist).
 
@@ -721,16 +722,16 @@ def _script():
     if not args:
         print("sys.path = [")
         for dir in sys.path:
-            print("    %r," % (dir,))
+            print(("    {!r},".format(dir)))
         print("]")
         def exists(path):
             if os.path.isdir(path):
                 return "exists"
             else:
                 return "doesn't exist"
-        print("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE)))
-        print("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE)))
-        print("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE)
+        print(("USER_BASE: {!r} ({})".format(USER_BASE, exists(USER_BASE))))
+        print(("USER_SITE: {!r} ({})".format(USER_SITE, exists(USER_BASE))))
+        print(("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE))
         sys.exit(0)
 
     buffer = []
@@ -740,7 +741,7 @@ def _script():
         buffer.append(USER_SITE)
 
     if buffer:
-        print(os.pathsep.join(buffer))
+        print((os.pathsep.join(buffer)))
         if ENABLE_USER_SITE:
             sys.exit(0)
         elif ENABLE_USER_SITE is False:
@@ -751,7 +752,7 @@ def _script():
             sys.exit(3)
     else:
         import textwrap
-        print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
+        print((textwrap.dedent(help % (sys.argv[0], os.pathsep))))
         sys.exit(10)
 
 if __name__ == '__main__':
diff --git a/python/voluptuous/setup.py b/python/voluptuous/setup.py
index 2fc07251dd..70d6cc23f8 100644
--- a/python/voluptuous/setup.py
+++ b/python/voluptuous/setup.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 try:
     from setuptools import setup
 except ImportError:
diff --git a/python/voluptuous/voluptuous.py b/python/voluptuous/voluptuous.py
index 132c3c476f..e7d0787b58 100644
--- a/python/voluptuous/voluptuous.py
+++ b/python/voluptuous/voluptuous.py
@@ -1,4 +1,3 @@
-# encoding: utf-8
 #
 # Copyright (C) 2010-2013 Alec Thomas 
 # All rights reserved.
@@ -93,17 +92,12 @@ from contextlib import contextmanager
 from functools import wraps
 
 
-if sys.version_info >= (3,):
-    import urllib.parse as urlparse
-    long = int
-    unicode = str
-    basestring = str
-    ifilter = filter
-    iteritems = lambda d: d.items()
-else:
-    from itertools import ifilter
-    import urlparse
-    iteritems = lambda d: d.iteritems()
+import urllib.parse as urlparse
+long = int
+str = str
+str = str
+ifilter = filter
+iteritems = lambda d: list(d.items())
 
 
 __author__ = 'Alec Thomas '
@@ -116,12 +110,12 @@ def raises(exc, msg=None, regex=None):
         yield
     except exc as e:
         if msg is not None:
-            assert str(e) == msg, '%r != %r' % (str(e), msg)
+            assert str(e) == msg, '{!r} != {!r}'.format(str(e), msg)
         if regex is not None:
-            assert re.search(regex, str(e)), '%r does not match %r' % (str(e), regex)
+            assert re.search(regex, str(e)), '{!r} does not match {!r}'.format(str(e), regex)
 
 
-class Undefined(object):
+class Undefined:
     def __nonzero__(self):
         return False
 
@@ -310,7 +304,7 @@ class VirtualPathComponent(str):
         return self.__str__()
 
 
-class Schema(object):
+class Schema:
     """A validation schema.
 
     The schema is a Python tree-like structure where nodes are pattern
@@ -348,7 +342,7 @@ class Schema(object):
         self._compiled = self._compile(schema)
 
     def __repr__(self):
-        return "" % (
+        return "".format(
             self.schema, self._extra_to_name.get(self.extra, '??'),
             self.required, id(self))
 
@@ -367,7 +361,7 @@ class Schema(object):
             return lambda _, v: v
         if isinstance(schema, Object):
             return self._compile_object(schema)
-        if isinstance(schema, collections.Mapping):
+        if isinstance(schema, collections.abc.Mapping):
             return self._compile_dict(schema)
         elif isinstance(schema, list):
             return self._compile_list(schema)
@@ -376,7 +370,7 @@ class Schema(object):
         type_ = type(schema)
         if type_ is type:
             type_ = schema
-        if type_ in (bool, int, long, str, unicode, float, complex, object,
+        if type_ in (bool, int, int, str, str, float, complex, object,
                      list, dict, type(None)) or callable(schema):
             return _compile_scalar(schema)
         raise SchemaError('unsupported schema data type %r' %
@@ -387,15 +381,15 @@ class Schema(object):
         invalid_msg = invalid_msg or 'mapping value'
 
         # Keys that may be required
-        all_required_keys = set(key for key in schema
+        all_required_keys = {key for key in schema
                                 if key is not Extra
                                 and ((self.required and not isinstance(key, (Optional, Remove)))
-                                     or isinstance(key, Required)))
+                                     or isinstance(key, Required))}
 
         # Keys that may have defaults
-        all_default_keys = set(key for key in schema
+        all_default_keys = {key for key in schema
                                if isinstance(key, Required)
-                               or isinstance(key, Optional))
+                               or isinstance(key, Optional)}
 
         _compiled_schema = {}
         for skey, svalue in iteritems(schema):
@@ -517,9 +511,9 @@ class Schema(object):
         def validate_object(path, data):
             if (schema.cls is not UNDEFINED
                     and not isinstance(data, schema.cls)):
-                raise ObjectInvalid('expected a {0!r}'.format(schema.cls), path)
+                raise ObjectInvalid('expected a {!r}'.format(schema.cls), path)
             iterable = _iterate_object(data)
-            iterable = ifilter(lambda item: item[1] is not None, iterable)
+            iterable = filter(lambda item: item[1] is not None, iterable)
             out = base_validate(path, iterable, {})
             return type(data)(**out)
 
@@ -864,8 +858,7 @@ def _iterate_object(obj):
         # maybe we have named tuple here?
         if hasattr(obj, '_asdict'):
             d = obj._asdict()
-    for item in iteritems(d):
-        yield item
+    yield from iteritems(d)
     try:
         slots = obj.__slots__
     except AttributeError:
@@ -882,10 +875,10 @@ class Object(dict):
 
     def __init__(self, schema, cls=UNDEFINED):
         self.cls = cls
-        super(Object, self).__init__(schema)
+        super().__init__(schema)
 
 
-class Marker(object):
+class Marker:
     """Mark nodes for special treatment."""
 
     def __init__(self, schema, msg=None):
@@ -934,7 +927,7 @@ class Optional(Marker):
     {'key2': 'value'}
     """
     def __init__(self, schema, msg=None, default=UNDEFINED):
-        super(Optional, self).__init__(schema, msg=msg)
+        super().__init__(schema, msg=msg)
         self.default = default_factory(default)
 
 
@@ -974,7 +967,7 @@ class Exclusive(Optional):
     ...             'social': {'social_network': 'barfoo', 'token': 'tEMp'}})
     """
     def __init__(self, schema, group_of_exclusion, msg=None):
-        super(Exclusive, self).__init__(schema, msg=msg)
+        super().__init__(schema, msg=msg)
         self.group_of_exclusion = group_of_exclusion
 
 
@@ -1021,7 +1014,7 @@ class Inclusive(Optional):
     """
 
     def __init__(self, schema, group_of_inclusion, msg=None):
-        super(Inclusive, self).__init__(schema, msg=msg)
+        super().__init__(schema, msg=msg)
         self.group_of_inclusion = group_of_inclusion
 
 
@@ -1040,7 +1033,7 @@ class Required(Marker):
     {'key': []}
     """
     def __init__(self, schema, msg=None, default=UNDEFINED):
-        super(Required, self).__init__(schema, msg=msg)
+        super().__init__(schema, msg=msg)
         self.default = default_factory(default)
 
 
@@ -1059,11 +1052,11 @@ class Remove(Marker):
     [1, 2, 3, 5, '7']
     """
     def __call__(self, v):
-        super(Remove, self).__call__(v)
+        super().__call__(v)
         return self.__class__
 
     def __repr__(self):
-        return "Remove(%r)" % (self.schema,)
+        return "Remove({!r})".format(self.schema)
 
 
 def Extra(_):
@@ -1075,7 +1068,7 @@ def Extra(_):
 # deprecated object, so we just leave an alias here instead.
 extra = Extra
 
-class Msg(object):
+class Msg:
     """Report a user-friendly message if a schema fails to validate.
 
     >>> validate = Schema(
@@ -1123,7 +1116,7 @@ class Msg(object):
                 raise (self.cls or Invalid)(self.msg)
 
     def __repr__(self):
-        return 'Msg(%s, %s, cls=%s)' % (self._schema, self.msg, self.cls)
+        return 'Msg({}, {}, cls={})'.format(self._schema, self.msg, self.cls)
 
 
 def message(default=None, cls=None):
@@ -1192,7 +1185,7 @@ def truth(f):
     return check
 
 
-class Coerce(object):
+class Coerce:
     """Coerce a value to a type.
 
     If the type constructor throws a ValueError or TypeError, the value
@@ -1226,7 +1219,7 @@ class Coerce(object):
             raise CoerceInvalid(msg)
 
     def __repr__(self):
-        return 'Coerce(%s, msg=%r)' % (self.type_name, self.msg)
+        return 'Coerce({}, msg={!r})'.format(self.type_name, self.msg)
 
 
 @message('value was not true', cls=TrueInvalid)
@@ -1299,7 +1292,7 @@ def Boolean(v):
     ... except MultipleInvalid as e:
     ...   assert isinstance(e.errors[0], BooleanInvalid)
     """
-    if isinstance(v, basestring):
+    if isinstance(v, str):
         v = v.lower()
         if v in ('1', 'true', 'yes', 'on', 'enable'):
             return True
@@ -1309,7 +1302,7 @@ def Boolean(v):
     return bool(v)
 
 
-class Any(object):
+class Any:
     """Use the first validated value.
 
     :param msg: Message to deliver to user if validation fails.
@@ -1360,7 +1353,7 @@ class Any(object):
 Or = Any
 
 
-class All(object):
+class All:
     """Value must pass all validators.
 
     The output of each validator is passed as input to the next.
@@ -1387,7 +1380,7 @@ class All(object):
         return v
 
     def __repr__(self):
-        return 'All(%s, msg=%r)' % (
+        return 'All({}, msg={!r})'.format(
             ", ".join(repr(v) for v in self.validators),
             self.msg
         )
@@ -1397,7 +1390,7 @@ class All(object):
 And = All
 
 
-class Match(object):
+class Match:
     """Value must be a string that matches the regular expression.
 
     >>> validate = Schema(Match(r'^0x[A-F0-9]+$'))
@@ -1417,7 +1410,7 @@ class Match(object):
     """
 
     def __init__(self, pattern, msg=None):
-        if isinstance(pattern, basestring):
+        if isinstance(pattern, str):
             pattern = re.compile(pattern)
         self.pattern = pattern
         self.msg = msg
@@ -1432,10 +1425,10 @@ class Match(object):
         return v
 
     def __repr__(self):
-        return 'Match(%r, msg=%r)' % (self.pattern.pattern, self.msg)
+        return 'Match({!r}, msg={!r})'.format(self.pattern.pattern, self.msg)
 
 
-class Replace(object):
+class Replace:
     """Regex substitution.
 
     >>> validate = Schema(All(Replace('you', 'I'),
@@ -1445,7 +1438,7 @@ class Replace(object):
     """
 
     def __init__(self, pattern, substitution, msg=None):
-        if isinstance(pattern, basestring):
+        if isinstance(pattern, str):
             pattern = re.compile(pattern)
         self.pattern = pattern
         self.substitution = substitution
@@ -1455,7 +1448,7 @@ class Replace(object):
         return self.pattern.sub(self.substitution, v)
 
     def __repr__(self):
-        return 'Replace(%r, %r, msg=%r)' % (self.pattern.pattern,
+        return 'Replace({!r}, {!r}, msg={!r})'.format(self.pattern.pattern,
                                             self.substitution,
                                             self.msg)
 
@@ -1540,7 +1533,7 @@ def PathExists(v):
     return os.path.exists(v)
 
 
-class Range(object):
+class Range:
     """Limit a value to a range.
 
     Either min or max may be omitted.
@@ -1596,7 +1589,7 @@ class Range(object):
                                                self.msg))
 
 
-class Clamp(object):
+class Clamp:
     """Clamp a value to a range.
 
     Either min or max may be omitted.
@@ -1622,14 +1615,14 @@ class Clamp(object):
         return v
 
     def __repr__(self):
-        return 'Clamp(min=%s, max=%s)' % (self.min, self.max)
+        return 'Clamp(min={}, max={})'.format(self.min, self.max)
 
 
 class LengthInvalid(Invalid):
     pass
 
 
-class Length(object):
+class Length:
     """The length of a value must be in a certain range."""
 
     def __init__(self, min=None, max=None, msg=None):
@@ -1647,14 +1640,14 @@ class Length(object):
         return v
 
     def __repr__(self):
-        return 'Length(min=%s, max=%s)' % (self.min, self.max)
+        return 'Length(min={}, max={})'.format(self.min, self.max)
 
 
 class DatetimeInvalid(Invalid):
     """The value is not a formatted datetime string."""
 
 
-class Datetime(object):
+class Datetime:
     """Validate that the value matches the datetime format."""
 
     DEFAULT_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
@@ -1680,7 +1673,7 @@ class InInvalid(Invalid):
     pass
 
 
-class In(object):
+class In:
     """Validate that a value is in a collection."""
 
     def __init__(self, container, msg=None):
@@ -1697,14 +1690,14 @@ class In(object):
         return v
 
     def __repr__(self):
-        return 'In(%s)' % (self.container,)
+        return 'In({})'.format(self.container)
 
 
 class NotInInvalid(Invalid):
     pass
 
 
-class NotIn(object):
+class NotIn:
     """Validate that a value is not in a collection."""
 
     def __init__(self, container, msg=None):
@@ -1721,7 +1714,7 @@ class NotIn(object):
         return v
 
     def __repr__(self):
-        return 'NotIn(%s)' % (self.container,)
+        return 'NotIn({})'.format(self.container)
 
 
 def Lower(v):
@@ -1774,7 +1767,7 @@ def Strip(v):
     return str(v).strip()
 
 
-class DefaultTo(object):
+class DefaultTo:
     """Sets a value to default_value if none provided.
 
     >>> s = Schema(DefaultTo(42))
@@ -1795,10 +1788,10 @@ class DefaultTo(object):
         return v
 
     def __repr__(self):
-        return 'DefaultTo(%s)' % (self.default_value(),)
+        return 'DefaultTo({})'.format(self.default_value())
 
 
-class SetTo(object):
+class SetTo:
     """Set a value, ignoring any previous value.
 
     >>> s = Schema(Any(int, SetTo(42)))
@@ -1815,14 +1808,14 @@ class SetTo(object):
         return self.value()
 
     def __repr__(self):
-        return 'SetTo(%s)' % (self.value(),)
+        return 'SetTo({})'.format(self.value())
 
 
 class ExactSequenceInvalid(Invalid):
     pass
 
 
-class ExactSequence(object):
+class ExactSequence:
     """Matches each element in a sequence against the corresponding element in
     the validators.
 
@@ -1857,14 +1850,14 @@ class ExactSequence(object):
                                                   for v in self.validators))
 
 
-class Literal(object):
+class Literal:
     def __init__(self, lit):
         self.lit = lit
 
     def __call__(self, value, msg=None):
         if self.lit != value:
             raise LiteralInvalid(
-                msg or '%s not match for %s' % (value, self.lit)
+                msg or '{} not match for {}'.format(value, self.lit)
             )
         else:
             return self.lit
@@ -1876,7 +1869,7 @@ class Literal(object):
         return repr(self.lit)
 
 
-class Unique(object):
+class Unique:
     """Ensure an iterable does not contain duplicate items.
 
     Only iterables convertable to a set are supported (native types and
@@ -1910,19 +1903,19 @@ class Unique(object):
             set_v = set(v)
         except TypeError as e:
             raise TypeInvalid(
-                self.msg or 'contains unhashable elements: {0}'.format(e))
+                self.msg or 'contains unhashable elements: {}'.format(e))
         if len(set_v) != len(v):
             seen = set()
-            dupes = list(set(x for x in v if x in seen or seen.add(x)))
+            dupes = list({x for x in v if x in seen or seen.add(x)})
             raise Invalid(
-                self.msg or 'contains duplicate items: {0}'.format(dupes))
+                self.msg or 'contains duplicate items: {}'.format(dupes))
         return v
 
     def __repr__(self):
         return 'Unique()'
 
 
-class Set(object):
+class Set:
     """Convert a list into a set.
 
     >>> s = Schema(Set())
@@ -1942,7 +1935,7 @@ class Set(object):
             set_v = set(v)
         except Exception as e:
             raise TypeInvalid(
-                self.msg or 'cannot be presented as set: {0}'.format(e))
+                self.msg or 'cannot be presented as set: {}'.format(e))
         return set_v
 
     def __repr__(self):
diff --git a/python/which/build.py b/python/which/build.py
index 3c8f09d39e..6f388c953b 100644
--- a/python/which/build.py
+++ b/python/which/build.py
@@ -22,6 +22,7 @@
     attributes).
 """
 
+from __future__ import print_function
 import os
 from os.path import basename, dirname, splitext, isfile, isdir, exists, \
                     join, abspath, normpath
@@ -129,7 +130,7 @@ def _run_in_dir(cmd, cwd, logstream=_RUN_DEFAULT_LOGSTREAM):
 def _rmtree_OnError(rmFunction, filePath, excInfo):
     if excInfo[0] == OSError:
         # presuming because file is read-only
-        os.chmod(filePath, 0777)
+        os.chmod(filePath, 0o777)
         rmFunction(filePath)
 def _rmtree(dirname):
     import shutil
@@ -192,12 +193,12 @@ def _listTargets(targets):
         nameWidth = max(nameWidth, len(name))
     nameWidth += 2  # space btwn name and doc
     format = "%%-%ds%%s" % nameWidth
-    print format % ("TARGET", "DESCRIPTION")
+    print((format % ("TARGET", "DESCRIPTION")))
     for name, func in sorted(targets.items()):
         doc = _first_paragraph(func.__doc__ or "", True)
         if len(doc) > (width - nameWidth):
             doc = doc[:(width-nameWidth-3)] + "..."
-        print format % (name, doc)
+        print((format % (name, doc)))
 
 
 # Recipe: first_paragraph (1.0.1) in /Users/trentm/tm/recipes/cookbook
@@ -234,7 +235,7 @@ def target_clean():
     ver = _get_project_version()
     dirs = ["dist", "build", "%s-%s" % (_project_name_, ver)]
     for d in dirs:
-        print "removing '%s'" % d
+        print(("removing '%s'" % d))
         if os.path.isdir(d): _rmtree(d)
 
     patterns = ["*.pyc", "*~", "MANIFEST",
@@ -243,7 +244,7 @@ def target_clean():
                ]
     for pattern in patterns:
         for file in glob.glob(pattern):
-            print "removing '%s'" % file
+            print(("removing '%s'" % file))
             os.unlink(file)
 
 
@@ -360,8 +361,8 @@ def target_upload():
 
     # Ensure have all the expected bits.
     expectedBits = [
-        re.compile("%s-.*\.zip$" % _project_name_),
-        re.compile("%s-.*\.web$" % _project_name_)
+        re.compile(r"%s-.*\.zip$" % _project_name_),
+        re.compile(r"%s-.*\.web$" % _project_name_)
     ]
     for expectedBit in expectedBits:
         for bit in bits:
@@ -409,13 +410,13 @@ def build(targets=[]):
     log.debug("build(targets=%r)" % targets)
     available = _getTargets()
     if not targets:
-        if available.has_key('default'):
+        if 'default' in available:
             return available['default']()
         else:   
             log.warn("No default target available. Doing nothing.")
     else:
         for target in targets:
-            if available.has_key(target):
+            if target in available:
                 retval = available[target]()
                 if retval:
                     raise Error("Error running '%s' target: retval=%s"\
diff --git a/python/which/test/test_which.py b/python/which/test/test_which.py
index b569769897..7698993b51 100644
--- a/python/which/test/test_which.py
+++ b/python/which/test/test_which.py
@@ -41,7 +41,7 @@ class WhichTestCase(unittest.TestCase):
         for app in self.testapps:
             path = os.path.join(self.tmpdir, app)
             open(path, 'wb').write('\n')
-            os.chmod(path, 0755)
+            os.chmod(path, 0o755)
 
     def tearDown(self):
         testsupport.rmtree(self.tmpdir)
@@ -66,7 +66,7 @@ class WhichTestCase(unittest.TestCase):
 
     def test_opt_version(self):
         output, error, retval = testsupport.run(self.which+' --version')
-        versionRe = re.compile("^which \d+\.\d+\.\d+$")
+        versionRe = re.compile(r"^which \d+\.\d+\.\d+$")
         versionMatch = versionRe.search(output.strip())
         self.failUnless(versionMatch,
                         "Version, '%s', from 'which --version' does not "\
diff --git a/python/which/test/testsupport.py b/python/which/test/testsupport.py
index 8ff519fada..2fdbd60e96 100644
--- a/python/which/test/testsupport.py
+++ b/python/which/test/testsupport.py
@@ -37,7 +37,7 @@ def run(argv):
     results.  Returns (, , ).
     Note: 'argv' may also just be the command string.
     """
-    if type(argv) in (types.ListType, types.TupleType):
+    if type(argv) in (list, tuple):
         cmd = _joinArgv(argv)
     else:
         cmd = argv
@@ -73,7 +73,7 @@ def run(argv):
 def _rmtreeOnError(rmFunction, filePath, excInfo):
     if excInfo[0] == OSError:
         # presuming because file is read-only
-        os.chmod(filePath, 0777)
+        os.chmod(filePath, 0o777)
         rmFunction(filePath)
 
 def rmtree(dirname):
diff --git a/python/which/which.py b/python/which/which.py
index 8dd790518a..fec39731ec 100644
--- a/python/which/which.py
+++ b/python/which/which.py
@@ -33,6 +33,7 @@ of where the match was found. For example:
     from HKLM\SOFTWARE\...\perl.exe
 """
 
+from __future__ import print_function
 _cmdlnUsage = """
     Show the full path of commands.
 
@@ -90,13 +91,13 @@ def _getRegisteredExecutable(exeName):
     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 +244,7 @@ def which(command, path=None, verbose=0, exts=None):
     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
@@ -280,17 +281,17 @@ def main(argv):
     try:
         optlist, 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 +319,9 @@ def main(argv):
         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
diff --git a/security/generate_mapfile.py b/security/generate_mapfile.py
index 4479553bf8..289e176370 100644
--- a/security/generate_mapfile.py
+++ b/security/generate_mapfile.py
@@ -13,16 +13,17 @@
 # but the Mozilla build system is already running a Python script to generate
 # the file so it's simpler to just do the replacement in Python.
 
+from __future__ import print_function
 import buildconfig
 
 
 def main(output, input):
     if buildconfig.substs['OS_ARCH'] not in ('Linux', 'SunOS', 'Darwin', 'FreeBSD'):
-        print "Error: unhandled OS_ARCH %s" % buildconfig.substs['OS_ARCH']
+        print("Error: unhandled OS_ARCH %s" % buildconfig.substs['OS_ARCH'])
         return 1
     is_linux = buildconfig.substs['OS_ARCH'] in ('Linux', 'SunOS', 'FreeBSD')
 
-    with open(input, 'rb') as f:
+    with open(input, 'r') as f:
         for line in f:
             line = line.rstrip()
             # Remove all lines containing ';-'
diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py
index 9c8efa915c..00e0f1a0dd 100755
--- a/security/manager/ssl/tests/unit/pycert.py
+++ b/security/manager/ssl/tests/unit/pycert.py
@@ -81,6 +81,7 @@ If a serial number is not explicitly specified, it is automatically
 generated based on the contents of the certificate.
 """
 
+from __future__ import print_function
 from pyasn1.codec.der import decoder
 from pyasn1.codec.der import encoder
 from pyasn1.type import constraint, namedtype, tag, univ, useful
@@ -694,4 +695,4 @@ def main(output, inputPath):
 # When run as a standalone program, this will read a specification from
 # stdin and output the certificate as PEM to stdout.
 if __name__ == '__main__':
-    print Certificate(sys.stdin).toPEM()
+    print(Certificate(sys.stdin).toPEM())
diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py
index d3c43deb4c..eda89d53fd 100755
--- a/security/manager/ssl/tests/unit/pykey.py
+++ b/security/manager/ssl/tests/unit/pykey.py
@@ -30,6 +30,7 @@ secp384r1: an ECC key on the curve secp384r1
 secp521r1: an ECC key on the curve secp521r1
 """
 
+from __future__ import print_function
 from pyasn1.codec.der import encoder
 from pyasn1.type import univ, namedtype
 from pyasn1_modules import rfc2459
@@ -109,7 +110,7 @@ class RSAKey(object):
     # For reference, when encoded as a subject public key info, the
     # base64-encoded sha-256 hash of this key is
     # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=
-    sharedRSA_N = long(
+    sharedRSA_N = int(
         '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857'
         '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a'
         'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c'
@@ -119,8 +120,8 @@ class RSAKey(object):
         '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a'
         '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3'
         'fe4923fa7251c431d503acda180a35ed8d', 16)
-    sharedRSA_E = 65537L
-    sharedRSA_D = long(
+    sharedRSA_E = 65537
+    sharedRSA_D = int(
         '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da'
         'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46'
         '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2'
@@ -130,31 +131,31 @@ class RSAKey(object):
         '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c'
         'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931'
         '5b62b30e6011f224725946eec57c6d9441', 16)
-    sharedRSA_P = long(
+    sharedRSA_P = int(
         '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb'
         'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f'
         '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d'
         'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177'
         '3ca5d19301f48c742b', 16)
-    sharedRSA_Q = long(
+    sharedRSA_Q = int(
         '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47'
         '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d'
         '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833'
         '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16'
         '5810a77b9845bc3127', 16)
-    sharedRSA_exp1 = long(
+    sharedRSA_exp1 = int(
         '0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35'
         '81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc'
         'f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66'
         '21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765'
         '5315be9c24d191992d', 16)
-    sharedRSA_exp2 = long(
+    sharedRSA_exp2 = int(
         '28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26'
         'ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1'
         'b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0'
         'aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a'
         '5a4a6287c151de2d', 16)
-    sharedRSA_coef = long(
+    sharedRSA_coef = int(
         '28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b'
         'e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab'
         'cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf'
@@ -164,7 +165,7 @@ class RSAKey(object):
     # For reference, when encoded as a subject public key info, the
     # base64-encoded sha-256 hash of this key is
     # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI=
-    alternateRSA_N = long(
+    alternateRSA_N = int(
         '00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f'
         'a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244'
         'c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313'
@@ -174,8 +175,8 @@ class RSAKey(object):
         'a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b'
         '35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457'
         '324ad7de86e6552f1d1e191d712168d3bb', 16)
-    alternateRSA_E = 65537L
-    alternateRSA_D = long(
+    alternateRSA_E = 65537
+    alternateRSA_D = int(
         '7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079'
         '0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732'
         '7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1'
@@ -185,38 +186,38 @@ class RSAKey(object):
         '857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0'
         '8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750'
         '78c4021a9a2c93c9a70390e9d0a54401', 16)
-    alternateRSA_P = long(
+    alternateRSA_P = int(
         '00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81'
         '258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d'
         '3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979'
         '9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f'
         '27b06fe09ddda7c0a1', 16)
-    alternateRSA_Q = long(
+    alternateRSA_Q = int(
         '00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708'
         '4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac'
         '6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb'
         'a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd'
         'fe764c1967b3e8cadb', 16)
-    alternateRSA_exp1 = long(
+    alternateRSA_exp1 = int(
         '01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d'
         '3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3'
         'c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27'
         '9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60'
         '9b5790a63c595181', 16)
-    alternateRSA_exp2 = long(
+    alternateRSA_exp2 = int(
         '0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a'
         'f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b'
         '1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733'
         'cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798'
         '1cd6234d571e90b7df', 16)
-    alternateRSA_coef = long(
+    alternateRSA_coef = int(
         '6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8'
         '594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6'
         '8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828'
         '27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a'
         '7b0df271e19a65c0', 16)
 
-    evRSA_N = long(
+    evRSA_N = int(
         '00b549895c9d00108d11a1f99f87a9e3d1a5db5dfaecf188da57bf641368'
         '8f2ce4722cff109038c17402c93a2a473dbd286aed3fdcd363cf5a291477'
         '01bdd818d7615bf9356bd5d3c8336aaa8c0971368a06c3cd4461b93e5142'
@@ -226,8 +227,8 @@ class RSAKey(object):
         '1aae8aa2ccce348a0169b80e28a2d70c1a960c6f335f2da09b9b643f5abf'
         'ba49e8aaa981e960e27d87480bdd55dd9417fa18509fbb554ccf81a4397e'
         '8ba8128a34bdf27865c189e5734fb22905', 16)
-    evRSA_E = 65537L
-    evRSA_D = long(
+    evRSA_E = 65537
+    evRSA_D = int(
         '00983d54f94d6f4c76eb23d6f93d78523530cf73b0d16254c6e781768d45'
         'f55681d1d02fb2bd2aac6abc1c389860935c52a0d8f41482010394778314'
         '1d864bff30803638a5c0152570ae9d18f3d8ca163efb475b0dddf32e7e16'
@@ -237,38 +238,38 @@ class RSAKey(object):
         'fe274ae89431a10640be7899b0011c5e5093a1834708689de100634dabde'
         '60fbd6aaefa3a33df34a1f36f60c043036b748d1c9ee98c4031a0afec60e'
         'fda0a990be524f5614eac4fdb34a52f951', 16)
-    evRSA_P = long(
+    evRSA_P = int(
         '00eadc2cb33e5ff1ca376bbd95bd6a1777d2cf4fac47545e92d11a6209b9'
         'd5e4ded47834581c169b3c884742a09ea187505c1ca55414d8d25b497632'
         'd5ec2aaa05233430fad49892777a7d68e038f561a3b8969e60b0a263defb'
         'fda48a9b0ff39d95bc88b15267c8ade97b5107948e41e433249d87f7db10'
         '9d5d74584d86bcc1d7', 16)
-    evRSA_Q = long(
+    evRSA_Q = int(
         '00c59ae576a216470248d944a55b9e9bf93299da341ec56e558eba821abc'
         'e1bf57b79cf411d2904c774f9dba1f15185f607b0574a08205d6ec28b66a'
         '36d634232eaaf2fea37561abaf9d644b68db38c9964cb8c96ec0ac61eba6'
         '4d05b446542f423976f5acde4ecc95536d2df578954f93f0cfd9c58fb78b'
         'a2a76dd5ac284dc883', 16)
-    evRSA_exp1 = long(
+    evRSA_exp1 = int(
         '00c1d2ef3906331c52aca64811f9fe425beb2898322fb3db51032ce8d7e9'
         'fc32240be92019cf2480fcd5e329837127118b2a59a1bfe06c883e3a4447'
         'f3f031cd9aebd0b8d368fc79740d2cce8eadb324df7f091eafe1564361d5'
         '4920b01b0471230e5e47d93f8ed33963c517bc4fc78f6d8b1f9eba85bcce'
         'db7033026508db6285', 16)
-    evRSA_exp2 = long(
+    evRSA_exp2 = int(
         '008521b8db5694dfbe804a315f9efc9b65275c5490acf2a3456d65e6e610'
         'bf9f647fc67501d4f5772f232ac70ccdef9fc2a6dfa415c7c41b6afc7af9'
         'd07c3ca03f7ed93c09f0b99f2c304434322f1071709bbc1baa4c91575fa6'
         'a959e07d4996956d95e22b57938b6e47c8d51ffedfc9bf888ce0d1a3e42b'
         '65a89bed4b91d3e5f5', 16)
-    evRSA_coef = long(
+    evRSA_coef = int(
         '00dc497b06b920c8be0b0077b798e977eef744a90ec2c5d7e6cbb22448fa'
         'c72da81a33180e0d8a02e831460c7fc7fd3a612f7b9930b61b799f8e908e'
         '632e9ba0409b6aa70b03a3ba787426263b5bd5843df8476edb5d14f6a861'
         '3ebaf5b9cd5ca42f5fbd2802e08e4e49e5709f5151510caa5ab2c1c6eb3e'
         'fe9295d16e8c25c916', 16)
 
-    evRSA2040_N = long(
+    evRSA2040_N = int(
         '00ca7020dc215f57914d343fae4a015111697af997a5ece91866499fc23f'
         '1b88a118cbd30b10d91c7b9a0d4ee8972fcae56caf57f25fc1275a2a4dbc'
         'b982428c32ef587bf2387410330a0ffb16b8029bd783969ef675f6de38c1'
@@ -278,8 +279,8 @@ class RSAKey(object):
         '4748a3aa3e09e9eb4d461ea0027e540926614728b9d243975cf9a0541bef'
         'd25e76b51f951110b0e7644fc7e38441791b6d2227384cb8004e23342372'
         'b1cf5cc3e73e31b7bbefa160e6862ebb', 16)
-    evRSA2040_E = 65537L
-    evRSA2040_D = long(
+    evRSA2040_E = 65537
+    evRSA2040_D = int(
         '00b2db74bce92362abf72955a638ae8720ba3033bb7f971caf39188d7542'
         'eaa1c1abb5d205b1e2111f4791c08911a2e141e8cfd7054702d23100b564'
         '2c06e1a31b118afd1f9a2f396cced425c501d91435ca8656766ced2b93bb'
@@ -289,38 +290,38 @@ class RSAKey(object):
         'c7a8206fdae1c1d04bdbb1980d4a298c5a17dae4186474a5f7835d882bce'
         'f24aef4ed6f149f94d96c9f7d78e647fc778a9017ff208d3b4a1768b1821'
         '62102cdab032fabbab38d5200a324649', 16)
-    evRSA2040_P = long(
+    evRSA2040_P = int(
         '0f3844d0d4d4d6a21acd76a6fc370b8550e1d7ec5a6234172e790f0029ae'
         '651f6d5c59330ab19802b9d7a207de7a1fb778e3774fdbdc411750633d8d'
         '1b3fe075006ffcfd1d10e763c7a9227d2d5f0c2dade1c9e659c350a159d3'
         '6bb986f12636d4f9942b288bc0fe21da8799477173144249ca2e389e6c5c'
         '25aa78c8cad7d4df', 16)
-    evRSA2040_Q = long(
+    evRSA2040_Q = int(
         '0d4d0bedd1962f07a1ead6b23a4ed67aeaf1270f052a6d29ba074945c636'
         '1a5c4f8f07bf859e067aed3f4e6e323ef2aa8a6acd340b0bdc7cfe4fd329'
         'e3c97f870c7f7735792c6aa9d0f7e7542a28ed6f01b0e55a2b8d9c24a65c'
         '6da314c95484f5c7c3954a81bb016b07ed17ee9b06039695bca059a79f8d'
         'c2423d328d5265a5', 16)
-    evRSA2040_exp1 = long(
+    evRSA2040_exp1 = int(
         '09f29a2ff05be8a96d614ba31b08935420a86c6bc42b99a6692ea0da5763'
         'f01e596959b7ddce73ef9c2e4f6e5b40710887500d44ba0c3cd3132cba27'
         '475f39c2df7552e2d123a2497a4f97064028769a48a3624657f72bf539f3'
         'd0de234feccd3be8a0aa90c6bf6e9b0bed43070a24d061ff3ed1751a3ef2'
         'ff7f6b90b9dbd5fb', 16)
-    evRSA2040_exp2 = long(
+    evRSA2040_exp2 = int(
         '01a659e170cac120a03be1cf8f9df1caa353b03593bd7476e5853bd874c2'
         '87388601c6c341ce9d1d284a5eef1a3a669d32b816a5eaecd8b7844fe070'
         '64b9bca0c2b318d540277b3f7f1510d386bb36e03b04771e5d229e88893e'
         '13b753bfb94518bb638e2404bd6e6a993c1668d93fc0b82ff08aaf34347d'
         '3fe8397108c87ca5', 16)
-    evRSA2040_coef = long(
+    evRSA2040_coef = int(
         '040257c0d4a21c0b9843297c65652db66304fb263773d728b6abfa06d37a'
         'c0ca62c628023e09e37dc0a901e4ce1224180e2582a3aa4b6a1a7b98e2bd'
         '70077aec14ac8ab66a755c71e0fc102471f9bbc1b46a95aa0b645f2c38e7'
         '6450289619ea3f5e8ae61037bffcf8249f22aa4e76e2a01909f3feb290ce'
         '93edf57b10ebe796', 16)
 
-    rsa2040_N = long(
+    rsa2040_N = int(
         '00bac0652fdfbc0055882ffbaeaceec88fa2d083c297dd5d40664dd3d90f'
         '52f9aa02bd8a50fba16e0fd991878ef475f9b350d9f8e3eb2abd717ce327'
         'b09788531f13df8e3e4e3b9d616bb8a41e5306eed2472163161051180127'
@@ -330,8 +331,8 @@ class RSAKey(object):
         '4fa544607e53fc685c7a55fd44a81d4142b6af51ea6fa6cea52965a2e8c5'
         'd84f3ca024d6fbb9b005b9651ce5d9f2ecf40ed404981a9ffc02636e311b'
         '095c6332a0c87dc39271b5551481774b', 16)
-    rsa2040_E = 65537L
-    rsa2040_D = long(
+    rsa2040_E = 65537
+    rsa2040_D = int(
         '603db267df97555cbed86b8df355034af28f1eb7f3e7829d239bcc273a7c'
         '7a69a10be8f21f1b6c4b02c6bae3731c3158b5bbff4605f57ab7b7b2a0cb'
         'a2ec005a2db5b1ea6e0aceea5bc745dcd2d0e9d6b80d7eb0ea2bc08127bc'
@@ -341,101 +342,101 @@ class RSAKey(object):
         '1fedb80612529b39f59d0a3f8180b5ba201132197f93a5815ded938df8e7'
         'd93c9b15766588f339bb59100afda494a7e452d7dd4c9a19ce2ec3a33a18'
         'b20f0b4dade172bee19f26f0dcbe41', 16)
-    rsa2040_P = long(
+    rsa2040_P = int(
         '0ec3869cb92d406caddf7a319ab29448bc505a05913707873361fc5b986a'
         '499fb65eeb815a7e37687d19f128087289d9bb8818e7bcca502c4900ad9a'
         'ece1179be12ff3e467d606fc820ea8f07ac9ebffe2236e38168412028822'
         '3e42dbe68dfd972a85a6447e51695f234da7911c67c9ab9531f33df3b994'
         '32d4ee88c9a4efbb', 16)
-    rsa2040_Q = long(
+    rsa2040_Q = int(
         '0ca63934549e85feac8e0f5604303fd1849fe88af4b7f7e1213283bbc7a2'
         'c2a509f9273c428c68de3db93e6145f1b400bd6d4a262614e9043ad362d4'
         'eba4a6b995399c8934a399912199e841d8e8dbff0489f69e663796730b29'
         '80530b31cb70695a21625ea2adccc09d930516fa872211a91e22dd89fd9e'
         'b7da8574b72235b1', 16)
-    rsa2040_exp1 = long(
+    rsa2040_exp1 = int(
         '0d7d3a75e17f65f8a658a485c4095c10a4f66979e2b73bca9cf8ef21253e'
         '1facac6d4791f58392ce8656f88f1240cc90c29653e3100c6d7a38ed44b1'
         '63b339e5f3b6e38912126c69b3ceff2e5192426d9649b6ffca1abb75d2ba'
         '2ed6d9a26aa383c5973d56216ff2edb90ccf887742a0f183ac92c94cf187'
         '657645c7772d9ad7', 16)
-    rsa2040_exp2 = long(
+    rsa2040_exp2 = int(
         '03f550194c117f24bea285b209058032f42985ff55acebe88b16df9a3752'
         '7b4e61dc91a68dbc9a645134528ce5f248bda2893c96cb7be79ee73996c7'
         'c22577f6c2f790406f3472adb3b211b7e94494f32c5c6fcc0978839fe472'
         '4c31b06318a2489567b4fca0337acb1b841227aaa5f6c74800a2306929f0'
         '2ce038bad943df41', 16)
-    rsa2040_coef = long(
+    rsa2040_coef = int(
         '080a7dbfa8c2584814c71664c56eb62ce4caf16afe88d4499159d674774a'
         '3a3ecddf1256c02fc91525c527692422d0aba94e5c41ee12dc71bb66f867'
         '9fa17e096f28080851ba046eb31885c1414e8985ade599d907af17453d1c'
         'caea2c0d06443f8367a6be154b125e390ee0d90f746f08801dd3f5367f59'
         'fba2e5a67c05f375', 16)
 
-    rsa1024_N = long(
+    rsa1024_N = int(
         '00d3a97440101eba8c5df9503e6f935eb52ffeb3ebe9d0dc5cace26f973c'
         'a94cbc0d9c31d66c0c013bce9c82d0d480328df05fb6bcd7990a5312ddae'
         '6152ad6ee61c8c1bdd8663c68bd36224a9882ae78e89f556dfdbe6f51da6'
         '112cbfc27c8a49336b41afdb75321b52b24a7344d1348e646351a551c757'
         '1ccda0b8fe35f61a75', 16)
-    rsa1024_E = 65537L
-    rsa1024_D = long(
+    rsa1024_E = 65537
+    rsa1024_D = int(
         '5b6708e185548fc07ff062dba3792363e106ff9177d60ee3227162391024'
         '1813f958a318f26db8b6a801646863ebbc69190d6c2f5e7723433e99666d'
         '76b3987892cd568f1f18451e8dc05477c0607ee348380ebb7f4c98d0c036'
         'a0260bc67b2dab46cbaa4ce87636d839d8fddcbae2da3e02e8009a21225d'
         'd7e47aff2f82699d', 16)
-    rsa1024_P = long(
+    rsa1024_P = int(
         '00fcdee570323e8fc399dbfc63d8c1569546fb3cd6886c628668ab1e1d0f'
         'ca71058febdf76d702970ad6579d80ac2f9521075e40ef8f3f39983bd819'
         '07e898bad3', 16)
-    rsa1024_Q = long(
+    rsa1024_Q = int(
         '00d64801c955b4eb75fbae230faa8b28c9cc5e258be63747ff5ac8d2af25'
         '3e9f6d6ce03ea2eb13ae0eb32572feb848c32ca00743635374338fedacd8'
         'c5885f7897', 16)
-    rsa1024_exp1 = long(
+    rsa1024_exp1 = int(
         '76c0526d5b1b28368a75d5d42a01b9a086e20b9310241e2cd2d0b166a278'
         'c694ff1e9d25d9193d47789b52bb0fa194de1af0b77c09007f12afdfeef9'
         '58d108c3', 16)
-    rsa1024_exp2 = long(
+    rsa1024_exp2 = int(
         '008a41898d8b14217c4d782cbd15ef95d0a660f45ed09a4884f4e170367b'
         '946d2f20398b907896890e88fe17b54bd7febe133ebc7720c86fe0649cca'
         '7ca121e05f', 16)
-    rsa1024_coef = long(
+    rsa1024_coef = int(
         '22db133445f7442ea2a0f582031ee214ff5f661972986f172651d8d6b4ec'
         '3163e99bff1c82fe58ec3d075c6d8f26f277020edb77c3ba821b9ba3ae18'
         'ff8cb2cb', 16)
 
-    rsa1016_N = long(
+    rsa1016_N = int(
         '00d29bb12fb84fddcd29b3a519cb66c43b8d8f8be545ba79384ce663ed03'
         'df75991600eb920790d2530cece544db99a71f05896a3ed207165534aa99'
         '057e47c47e3bc81ada6fa1e12e37268b5046a55268f9dad7ccb485d81a2e'
         '19d50d4f0b6854acaf6d7be69d9a083136e15afa8f53c1c8c84fc6077279'
         'dd0e55d7369a5bdd', 16)
-    rsa1016_E = 65537L
-    rsa1016_D = long(
+    rsa1016_E = 65537
+    rsa1016_D = int(
         '3c4965070bf390c251d5a2c5277c5b5fd0bdee85cad7fe2b27982bb28511'
         '4a507004036ae1cf8ae54b25e4db39215abd7e903f618c2d8b2f08cc6cd1'
         '2dbccd72205e4945b6b3df389e5e43de0a148bb2c84e2431fdbe5920b044'
         'bb272f45ecff0721b7dfb60397fc613a9ea35c22300530cae8f9159c534d'
         'f3bf0910951901', 16)
-    rsa1016_P = long(
+    rsa1016_P = int(
         '0f9f17597c85b8051b9c69afb55ef576c996dbd09047d0ccde5b9d60ea5c'
         '67fe4fac67be803f4b6ac5a3f050f76b966fb14f5cf105761e5ade6dd960'
         'b183ba55', 16)
-    rsa1016_Q = long(
+    rsa1016_Q = int(
         '0d7b637112ce61a55168c0f9c9386fb279ab40cba0d549336bba65277263'
         'aac782611a2c81d9b635cf78c40018859e018c5e9006d12e3d2ee6f346e7'
         '9fa43369', 16)
-    rsa1016_exp1 = long(
+    rsa1016_exp1 = int(
         '09fd6c9a3ea6e91ae32070f9fc1c210ff9352f97be5d1eeb951bb39681e9'
         'dc5b672a532221b3d8900c9a9d99b9d0a4e102dc450ca1b87b0b1389de65'
         '16c0ae0d', 16)
-    rsa1016_exp2 = long(
+    rsa1016_exp2 = int(
         '0141b832491b7dd4a83308920024c79cae64bd447df883bb4c5672a96bab'
         '48b7123b34f26324452cdceb17f21e570e347cbe2fd4c2d8f9910eac2cb6'
         'd895b8c9', 16)
-    rsa1016_coef = long(
+    rsa1016_coef = int(
         '0458dd6aee18c88b2f9b81f1bc3075ae20dc1f9973d20724f20b06043d61'
         '47c8789d4a07ae88bc82c8438c893e017b13947f62e0b18958a31eb664b1'
         '9e64d3e0', 16)
@@ -575,11 +576,11 @@ secp521r1 = univ.ObjectIdentifier('1.3.132.0.35')
 # The third number is the parameter b of the definition of the curve
 #   E: y^2 = x^3 + ax + b (a in this case is 0)
 # The fourth and fifth numbers constitute the base point G.
-secp256k1Params = (long('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16),
-                   long('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16),
+secp256k1Params = (int('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16),
+                   int('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16),
                    7,
-                   long('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16),
-                   long('483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', 16))
+                   int('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16),
+                   int('483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', 16))
 
 def longToEvenLengthHexString(val):
     h = format(val, 'x')
@@ -703,4 +704,4 @@ def main(output, inputPath):
 # When run as a standalone program, this will read a specification from
 # stdin and output the certificate as PEM to stdout.
 if __name__ == '__main__':
-    print keyFromSpecification(sys.stdin.read()).toPEM()
+    print(keyFromSpecification(sys.stdin.read()).toPEM())
diff --git a/security/manager/ssl/tests/unit/test_cert_version/generate.py b/security/manager/ssl/tests/unit/test_cert_version/generate.py
index b99cbefe2c..39f69f7a07 100755
--- a/security/manager/ssl/tests/unit/test_cert_version/generate.py
+++ b/security/manager/ssl/tests/unit/test_cert_version/generate.py
@@ -58,10 +58,10 @@ basicConstraintsCA = 'extension:basicConstraints:cA,'
 
 writeCertspec('ca', 'ca', [keyUsage, basicConstraintsCA])
 
-for versionStr, versionVal in versions.iteritems():
+for versionStr, versionVal in versions.items():
     # intermediates
     versionText = 'version:%s' % versionVal
-    for basicConstraintsType, basicConstraintsExtension in basicConstraintsTypes.iteritems():
+    for basicConstraintsType, basicConstraintsExtension in basicConstraintsTypes.items():
         intermediateName = 'int-%s-%s' % (versionStr, basicConstraintsType)
         writeCertspec('ca', intermediateName,
                       [keyUsage, versionText, basicConstraintsExtension])
@@ -69,13 +69,13 @@ for versionStr, versionVal in versions.iteritems():
 
     # end-entities
     versionText = 'version:%s' % versionVal
-    for basicConstraintsType, basicConstraintsExtension in basicConstraintsTypes.iteritems():
+    for basicConstraintsType, basicConstraintsExtension in basicConstraintsTypes.items():
         writeCertspec('ca', 'ee-%s-%s' % (versionStr, basicConstraintsType),
                       [versionText, basicConstraintsExtension])
 
     # self-signed certificates
     versionText = 'version:%s' % versionVal
-    for basicConstraintsType, basicConstraintsExtension in basicConstraintsTypes.iteritems():
+    for basicConstraintsType, basicConstraintsExtension in basicConstraintsTypes.items():
         selfSignedName = 'ss-%s-%s' % (versionStr, basicConstraintsType)
         writeCertspec(selfSignedName, selfSignedName,
                       [versionText, basicConstraintsExtension])
diff --git a/security/manager/ssl/tests/unit/test_content_signing/pysign.py b/security/manager/ssl/tests/unit/test_content_signing/pysign.py
index c68c45b52d..3593b15d18 100644
--- a/security/manager/ssl/tests/unit/test_content_signing/pysign.py
+++ b/security/manager/ssl/tests/unit/test_content_signing/pysign.py
@@ -15,6 +15,7 @@ You can use pysign.py like this:
 cat test.txt | python pysign.py > test.txt.signature
 """
 
+from __future__ import print_function
 import base64
 import binascii
 import ecc
@@ -26,4 +27,4 @@ data = stdin.read()
 
 key = ecc.Key.Key.decode(binascii.unhexlify(pykey.ECCKey.secp384r1Encoded))
 sig = key.sign("Content-Signature:\00" + data, 'sha384')
-print base64.b64encode(sig).replace('+', '-').replace('/', '_')
+print(base64.b64encode(sig).replace('+', '-').replace('/', '_'))
diff --git a/security/nss/automation/release/nss-release-helper.py b/security/nss/automation/release/nss-release-helper.py
index 9e6ab9868b..8fdfe10b10 100644
--- a/security/nss/automation/release/nss-release-helper.py
+++ b/security/nss/automation/release/nss-release-helper.py
@@ -3,6 +3,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import sys
 import shutil
@@ -34,12 +35,12 @@ abi_report_files = ['automation/abi-check/expected-report-libfreebl3.so.txt',
 
 
 def check_call_noisy(cmd, *args, **kwargs):
-    print("Executing command: {}".format(cmd))
+    print(("Executing command: {}".format(cmd)))
     check_call(cmd, *args, **kwargs)
 
 
 def exit_with_failure(what):
-    print("failure: {}".format(what))
+    print(("failure: {}".format(what)))
     sys.exit(2)
 
 
@@ -229,7 +230,7 @@ def set_all_lib_versions(version, major, minor, patch, build):
         print("You're increasing the minor (or major) version:")
         print("- erasing ABI comparison expectations")
         new_branch = "NSS_" + str(old_major) + "_" + str(old_minor) + "_BRANCH"
-        print("- setting reference branch to the branch of the previous version: " + new_branch)
+        print(("- setting reference branch to the branch of the previous version: " + new_branch))
         with open(abi_base_version_file, "w") as abi_base:
             abi_base.write("%s\n" % new_branch)
         for report_file in abi_report_files:
@@ -303,7 +304,7 @@ def create_nss_release_archive():
     check_call_noisy(["hg", "archive", "-r", nssreltag, "--prefix=nss-" + nssrel + "/nss",
                       stagedir + "/" + nssreltag + "/src/" + nss_tar, "-X", ".hgtags"])
     check_call_noisy(["tar", "-xz", "-C", nss_stagedir, "-f", nsprtar_with_path])
-    print("changing to directory " + nss_stagedir)
+    print(("changing to directory " + nss_stagedir))
     os.chdir(nss_stagedir)
     check_call_noisy(["tar", "-xz", "-f", nss_tar])
     check_call_noisy(["mv", "-i", "nspr-" + nsprrel + "/nspr", "nss-" + nssrel + "/"])
@@ -314,7 +315,7 @@ def create_nss_release_archive():
     check_call_noisy(["tar", "-cz", "--remove-files", "-f", nss_nspr_tar, "nss-" + nssrel])
     check_call("sha1sum " + nss_tar + " " + nss_nspr_tar + " > SHA1SUMS", shell=True)
     check_call("sha256sum " + nss_tar + " " + nss_nspr_tar + " > SHA256SUMS", shell=True)
-    print("created directory " + nss_stagedir + " with files:")
+    print(("created directory " + nss_stagedir + " with files:"))
     check_call_noisy(["ls", "-l"])
 
 
diff --git a/security/nss/coreconf/check_cc.py b/security/nss/coreconf/check_cc.py
index d0736af7d6..ab48480a67 100644
--- a/security/nss/coreconf/check_cc.py
+++ b/security/nss/coreconf/check_cc.py
@@ -1,12 +1,13 @@
 #!/usr/bin/env python
 
+from __future__ import print_function
 import os
 import subprocess
 import sys
 
 def main():
     if sys.platform == 'win32' or len(sys.argv) < 2:
-        print(0)
+        print((0))
     else:
         cc = os.environ.get('CC', 'cc')
         try:
@@ -20,7 +21,7 @@ def main():
         except OSError:
             # We probably just don't have CC/cc.
             cc_is_arg = False
-        print(int(cc_is_arg))
+        print((int(cc_is_arg)))
 
 if __name__ == '__main__':
     main()
diff --git a/security/nss/coreconf/werror.py b/security/nss/coreconf/werror.py
index 2f622c5e11..6fa3367165 100644
--- a/security/nss/coreconf/werror.py
+++ b/security/nss/coreconf/werror.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+from __future__ import print_function
 import os
 import subprocess
 
@@ -43,7 +44,7 @@ def main():
 
     def set_warning(warning, contra=''):
         if warning_supported(warning):
-            print('-W%s%s' % (contra, warning))
+            print(('-W%s%s' % (contra, warning)))
 
     if cc_is_clang:
         # clang is unable to handle glib's expansion of strcmp and similar for
diff --git a/security/nss/gtests/google_test/gtest/scripts/fuse_gtest_files.py b/security/nss/gtests/google_test/gtest/scripts/fuse_gtest_files.py
index d0dd464fe8..f89ec05b01 100755
--- a/security/nss/gtests/google_test/gtest/scripts/fuse_gtest_files.py
+++ b/security/nss/gtests/google_test/gtest/scripts/fuse_gtest_files.py
@@ -56,6 +56,7 @@ https://github.com/google/googletest/blob/master/googletest/docs/advanced.md for
 more information.
 """
 
+from __future__ import print_function
 __author__ = 'wan@google.com (Zhanyong Wan)'
 
 import os
@@ -93,8 +94,8 @@ def VerifyFileExists(directory, relative_path):
   """
 
   if not os.path.isfile(os.path.join(directory, relative_path)):
-    print('ERROR: Cannot find %s in directory %s.' % (relative_path,
-                                                      directory))
+    print(('ERROR: Cannot find %s in directory %s.' % (relative_path,
+                                                      directory)))
     print('Please either specify a valid project root directory '
           'or omit it on the command line.')
     sys.exit(1)
@@ -122,8 +123,8 @@ def VerifyOutputFile(output_dir, relative_path):
     # TODO(wan@google.com): The following user-interaction doesn't
     # work with automated processes.  We should provide a way for the
     # Makefile to force overwriting the files.
-    print('%s already exists in directory %s - overwrite it? (y/N) ' %
-          (relative_path, output_dir))
+    print(('%s already exists in directory %s - overwrite it? (y/N) ' %
+          (relative_path, output_dir)))
     answer = sys.stdin.readline().strip()
     if answer not in ['y', 'Y']:
       print('ABORTED.')
diff --git a/security/nss/gtests/google_test/gtest/scripts/gen_gtest_pred_impl.py b/security/nss/gtests/google_test/gtest/scripts/gen_gtest_pred_impl.py
index e09a6e0177..533ce60816 100755
--- a/security/nss/gtests/google_test/gtest/scripts/gen_gtest_pred_impl.py
+++ b/security/nss/gtests/google_test/gtest/scripts/gen_gtest_pred_impl.py
@@ -46,6 +46,7 @@ directory where the script is.  It also generates the accompanying
 unit test in file gtest_pred_impl_unittest.cc.
 """
 
+from __future__ import print_function
 __author__ = 'wan@google.com (Zhanyong Wan)'
 
 import os
@@ -184,7 +185,7 @@ def Title(word):
 def OneTo(n):
   """Returns the list [1, 2, 3, ..., n]."""
 
-  return range(1, n + 1)
+  return list(range(1, n + 1))
 
 
 def Iter(n, format, sep=''):
@@ -308,12 +309,12 @@ def GenerateFile(path, content):
   """Given a file path and a content string
      overwrites it with the given content.
   """
-  print 'Updating file %s . . .' % path
-  f = file(path, 'w+')
-  print >>f, content,
+  print('Updating file %s . . .' % path)
+  f = open(path, 'w+')
+  print(content, end=' ', file=f)
   f.close()
 
-  print 'File %s has been updated.' % path
+  print('File %s has been updated.' % path)
 
 
 def GenerateHeader(n):
@@ -720,8 +721,8 @@ def _Main():
   unit test."""
 
   if len(sys.argv) != 2:
-    print __doc__
-    print 'Author: ' + __author__
+    print(__doc__)
+    print('Author: ' + __author__)
     sys.exit(1)
 
   n = int(sys.argv[1])
diff --git a/security/nss/gtests/google_test/gtest/scripts/release_docs.py b/security/nss/gtests/google_test/gtest/scripts/release_docs.py
index 8d24f28fdf..2ab6bbbf34 100755
--- a/security/nss/gtests/google_test/gtest/scripts/release_docs.py
+++ b/security/nss/gtests/google_test/gtest/scripts/release_docs.py
@@ -61,6 +61,7 @@ EXAMPLE
        $ svn commit -m "release wiki pages for v2.6"
 """
 
+from __future__ import print_function
 __author__ = 'wan@google.com (Zhanyong Wan)'
 
 import os
@@ -127,11 +128,11 @@ class WikiBrancher(object):
   def BranchFiles(self):
     """Branches the .wiki files needed to be branched."""
 
-    print 'Branching %d .wiki files:' % (len(self.files_to_branch),)
+    print('Branching %d .wiki files:' % (len(self.files_to_branch),))
     os.chdir(self.wiki_dir)
     for f in self.files_to_branch:
       command = 'svn cp %s %s%s' % (f, self.version_prefix, f)
-      print command
+      print(command)
       os.system(command)
 
   def UpdateLinksInBranchedFiles(self):
@@ -139,10 +140,10 @@ class WikiBrancher(object):
     for f in self.files_to_branch:
       source_file = os.path.join(self.wiki_dir, f)
       versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f)
-      print 'Updating links in %s.' % (versioned_file,)
-      text = file(source_file, 'r').read()
+      print('Updating links in %s.' % (versioned_file,))
+      text = open(source_file, 'r').read()
       new_text = self.search_for_re.sub(self.replace_with, text)
-      file(versioned_file, 'w').write(new_text)
+      open(versioned_file, 'w').write(new_text)
 
 
 def main():
diff --git a/security/nss/gtests/google_test/gtest/scripts/upload.py b/security/nss/gtests/google_test/gtest/scripts/upload.py
index eba571142f..c1df773b09 100755
--- a/security/nss/gtests/google_test/gtest/scripts/upload.py
+++ b/security/nss/gtests/google_test/gtest/scripts/upload.py
@@ -46,7 +46,8 @@ against by using the '--rev' option.
 # This code is derived from appcfg.py in the App Engine SDK (open source),
 # and from ASPN recipe #146306.
 
-import cookielib
+from __future__ import print_function
+import six.moves.http_cookiejar
 import getpass
 import logging
 import md5
@@ -57,9 +58,10 @@ import re
 import socket
 import subprocess
 import sys
-import urllib
-import urllib2
-import urlparse
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
+import six.moves.urllib.parse
+import six
 
 try:
   import readline
@@ -94,15 +96,15 @@ def GetEmail(prompt):
       last_email = last_email_file.readline().strip("\n")
       last_email_file.close()
       prompt += " [%s]" % last_email
-    except IOError, e:
+    except IOError as e:
       pass
-  email = raw_input(prompt + ": ").strip()
+  email = input(prompt + ": ").strip()
   if email:
     try:
       last_email_file = open(last_email_file_name, "w")
       last_email_file.write(email)
       last_email_file.close()
-    except IOError, e:
+    except IOError as e:
       pass
   else:
     email = last_email
@@ -118,20 +120,20 @@ def StatusUpdate(msg):
     msg: The string to print.
   """
   if verbosity > 0:
-    print msg
+    print(msg)
 
 
 def ErrorExit(msg):
   """Print an error message to stderr and exit."""
-  print >>sys.stderr, msg
+  print(msg, file=sys.stderr)
   sys.exit(1)
 
 
-class ClientLoginError(urllib2.HTTPError):
+class ClientLoginError(six.moves.urllib.error.HTTPError):
   """Raised to indicate there was an error authenticating with ClientLogin."""
 
   def __init__(self, url, code, msg, headers, args):
-    urllib2.HTTPError.__init__(self, url, code, msg, headers, None)
+    six.moves.urllib.error.HTTPError.__init__(self, url, code, msg, headers, None)
     self.args = args
     self.reason = args["Error"]
 
@@ -177,10 +179,10 @@ class AbstractRpcServer(object):
   def _CreateRequest(self, url, data=None):
     """Creates a new urllib request."""
     logging.debug("Creating request for: '%s' with payload:\n%s", url, data)
-    req = urllib2.Request(url, data=data)
+    req = six.moves.urllib.request.Request(url, data=data)
     if self.host_override:
       req.add_header("Host", self.host_override)
-    for key, value in self.extra_headers.iteritems():
+    for key, value in self.extra_headers.items():
       req.add_header(key, value)
     return req
 
@@ -204,7 +206,7 @@ class AbstractRpcServer(object):
       account_type = "HOSTED"
     req = self._CreateRequest(
         url="https://www.google.com/accounts/ClientLogin",
-        data=urllib.urlencode({
+        data=six.moves.urllib.parse.urlencode({
             "Email": email,
             "Passwd": password,
             "service": "ah",
@@ -218,7 +220,7 @@ class AbstractRpcServer(object):
       response_dict = dict(x.split("=")
                            for x in response_body.split("\n") if x)
       return response_dict["Auth"]
-    except urllib2.HTTPError, e:
+    except six.moves.urllib.error.HTTPError as e:
       if e.code == 403:
         body = e.read()
         response_dict = dict(x.split("=", 1) for x in body.split("\n") if x)
@@ -240,14 +242,14 @@ class AbstractRpcServer(object):
     continue_location = "http://localhost/"
     args = {"continue": continue_location, "auth": auth_token}
     req = self._CreateRequest("http://%s/_ah/login?%s" %
-                              (self.host, urllib.urlencode(args)))
+                              (self.host, six.moves.urllib.parse.urlencode(args)))
     try:
       response = self.opener.open(req)
-    except urllib2.HTTPError, e:
+    except six.moves.urllib.error.HTTPError as e:
       response = e
     if (response.code != 302 or
         response.info()["location"] != continue_location):
-      raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg,
+      raise six.moves.urllib.error.HTTPError(req.get_full_url(), response.code, response.msg,
                               response.headers, response.fp)
     self.authenticated = True
 
@@ -270,34 +272,34 @@ class AbstractRpcServer(object):
       credentials = self.auth_function()
       try:
         auth_token = self._GetAuthToken(credentials[0], credentials[1])
-      except ClientLoginError, e:
+      except ClientLoginError as e:
         if e.reason == "BadAuthentication":
-          print >>sys.stderr, "Invalid username or password."
+          print("Invalid username or password.", file=sys.stderr)
           continue
         if e.reason == "CaptchaRequired":
-          print >>sys.stderr, (
+          print((
               "Please go to\n"
               "https://www.google.com/accounts/DisplayUnlockCaptcha\n"
-              "and verify you are a human.  Then try again.")
+              "and verify you are a human.  Then try again."), file=sys.stderr)
           break
         if e.reason == "NotVerified":
-          print >>sys.stderr, "Account not verified."
+          print("Account not verified.", file=sys.stderr)
           break
         if e.reason == "TermsNotAgreed":
-          print >>sys.stderr, "User has not agreed to TOS."
+          print("User has not agreed to TOS.", file=sys.stderr)
           break
         if e.reason == "AccountDeleted":
-          print >>sys.stderr, "The user account has been deleted."
+          print("The user account has been deleted.", file=sys.stderr)
           break
         if e.reason == "AccountDisabled":
-          print >>sys.stderr, "The user account has been disabled."
+          print("The user account has been disabled.", file=sys.stderr)
           break
         if e.reason == "ServiceDisabled":
-          print >>sys.stderr, ("The user's access to the service has been "
-                               "disabled.")
+          print(("The user's access to the service has been "
+                               "disabled."), file=sys.stderr)
           break
         if e.reason == "ServiceUnavailable":
-          print >>sys.stderr, "The service is not available; try again later."
+          print("The service is not available; try again later.", file=sys.stderr)
           break
         raise
       self._GetAuthCookie(auth_token)
@@ -334,7 +336,7 @@ class AbstractRpcServer(object):
         args = dict(kwargs)
         url = "http://%s%s" % (self.host, request_path)
         if args:
-          url += "?" + urllib.urlencode(args)
+          url += "?" + six.moves.urllib.parse.urlencode(args)
         req = self._CreateRequest(url=url, data=payload)
         req.add_header("Content-Type", content_type)
         try:
@@ -342,7 +344,7 @@ class AbstractRpcServer(object):
           response = f.read()
           f.close()
           return response
-        except urllib2.HTTPError, e:
+        except six.moves.urllib.error.HTTPError as e:
           if tries > 3:
             raise
           elif e.code == 401:
@@ -372,35 +374,35 @@ class HttpRpcServer(AbstractRpcServer):
     Returns:
       A urllib2.OpenerDirector object.
     """
-    opener = urllib2.OpenerDirector()
-    opener.add_handler(urllib2.ProxyHandler())
-    opener.add_handler(urllib2.UnknownHandler())
-    opener.add_handler(urllib2.HTTPHandler())
-    opener.add_handler(urllib2.HTTPDefaultErrorHandler())
-    opener.add_handler(urllib2.HTTPSHandler())
+    opener = six.moves.urllib.request.OpenerDirector()
+    opener.add_handler(six.moves.urllib.request.ProxyHandler())
+    opener.add_handler(six.moves.urllib.request.UnknownHandler())
+    opener.add_handler(six.moves.urllib.request.HTTPHandler())
+    opener.add_handler(six.moves.urllib.request.HTTPDefaultErrorHandler())
+    opener.add_handler(six.moves.urllib.request.HTTPSHandler())
     opener.add_handler(urllib2.HTTPErrorProcessor())
     if self.save_cookies:
       self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies")
-      self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file)
+      self.cookie_jar = six.moves.http_cookiejar.MozillaCookieJar(self.cookie_file)
       if os.path.exists(self.cookie_file):
         try:
           self.cookie_jar.load()
           self.authenticated = True
           StatusUpdate("Loaded authentication cookies from %s" %
                        self.cookie_file)
-        except (cookielib.LoadError, IOError):
+        except (six.moves.http_cookiejar.LoadError, IOError):
           # Failed to load cookies - just ignore them.
           pass
       else:
         # Create an empty cookie file with mode 600
-        fd = os.open(self.cookie_file, os.O_CREAT, 0600)
+        fd = os.open(self.cookie_file, os.O_CREAT, 0o600)
         os.close(fd)
       # Always chmod the cookie file
-      os.chmod(self.cookie_file, 0600)
+      os.chmod(self.cookie_file, 0o600)
     else:
       # Don't save cookies across runs of update.py.
-      self.cookie_jar = cookielib.CookieJar()
-    opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar))
+      self.cookie_jar = six.moves.http_cookiejar.CookieJar()
+    opener.add_handler(six.moves.urllib.request.HTTPCookieProcessor(self.cookie_jar))
     return opener
 
 
@@ -575,7 +577,7 @@ def RunShellWithReturnCode(command, print_output=False,
       line = p.stdout.readline()
       if not line:
         break
-      print line.strip("\n")
+      print(line.strip("\n"))
       output_array.append(line)
     output = "".join(output_array)
   else:
@@ -583,7 +585,7 @@ def RunShellWithReturnCode(command, print_output=False,
   p.wait()
   errout = p.stderr.read()
   if print_output and errout:
-    print >>sys.stderr, errout
+    print(errout, file=sys.stderr)
   p.stdout.close()
   p.stderr.close()
   return output, p.returncode
@@ -629,11 +631,11 @@ class VersionControlSystem(object):
     """Show an "are you sure?" prompt if there are unknown files."""
     unknown_files = self.GetUnknownFiles()
     if unknown_files:
-      print "The following files are not added to version control:"
+      print("The following files are not added to version control:")
       for line in unknown_files:
-        print line
+        print(line)
       prompt = "Are you sure to continue?(y/N) "
-      answer = raw_input(prompt).strip()
+      answer = input(prompt).strip()
       if answer != "y":
         ErrorExit("User aborted")
 
@@ -685,13 +687,13 @@ class VersionControlSystem(object):
       else:
         type = "current"
       if len(content) > MAX_UPLOAD_SIZE:
-        print ("Not uploading the %s file for %s because it's too large." %
-               (type, filename))
+        print(("Not uploading the %s file for %s because it's too large." %
+               (type, filename)))
         file_too_large = True
         content = ""
       checksum = md5.new(content).hexdigest()
       if options.verbose > 0 and not file_too_large:
-        print "Uploading %s file for %s" % (type, filename)
+        print("Uploading %s file for %s" % (type, filename))
       url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id)
       form_fields = [("filename", filename),
                      ("status", status),
@@ -770,8 +772,8 @@ class SubversionVCS(VersionControlSystem):
       words = line.split()
       if len(words) == 2 and words[0] == "URL:":
         url = words[1]
-        scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
-        username, netloc = urllib.splituser(netloc)
+        scheme, netloc, path, params, query, fragment = six.moves.urllib.parse.urlparse(url)
+        username, netloc = six.moves.urllib.parse.splituser(netloc)
         if username:
           logging.info("Removed username from base URL")
         if netloc.endswith("svn.python.org"):
@@ -789,12 +791,12 @@ class SubversionVCS(VersionControlSystem):
           logging.info("Guessed CollabNet base = %s", base)
         elif netloc.endswith(".googlecode.com"):
           path = path + "/"
-          base = urlparse.urlunparse(("http", netloc, path, params,
+          base = six.moves.urllib.parse.urlunparse(("http", netloc, path, params,
                                       query, fragment))
           logging.info("Guessed Google Code base = %s", base)
         else:
           path = path + "/"
-          base = urlparse.urlunparse((scheme, netloc, path, params,
+          base = six.moves.urllib.parse.urlunparse((scheme, netloc, path, params,
                                       query, fragment))
           logging.info("Guessed base = %s", base)
         return base
@@ -1202,8 +1204,8 @@ def UploadSeparatePatches(issue, rpc_server, patchset, data, options):
   rv = []
   for patch in patches:
     if len(patch[1]) > MAX_UPLOAD_SIZE:
-      print ("Not uploading the patch for " + patch[0] +
-             " because the file is too large.")
+      print(("Not uploading the patch for " + patch[0] +
+             " because the file is too large."))
       continue
     form_fields = [("filename", patch[0])]
     if not options.download_base:
@@ -1211,7 +1213,7 @@ def UploadSeparatePatches(issue, rpc_server, patchset, data, options):
     files = [("data", "data.diff", patch[1])]
     ctype, body = EncodeMultipartFormData(form_fields, files)
     url = "/%d/upload_patch/%d" % (int(issue), int(patchset))
-    print "Uploading patch for " + patch[0]
+    print("Uploading patch for " + patch[0])
     response_body = rpc_server.Send(url, body, content_type=ctype)
     lines = response_body.splitlines()
     if not lines or lines[0] != "OK":
@@ -1238,7 +1240,8 @@ def GuessVCS(options):
     out, returncode = RunShellWithReturnCode(["hg", "root"])
     if returncode == 0:
       return MercurialVCS(options, out.strip())
-  except OSError, (errno, message):
+  except OSError as xxx_todo_changeme:
+    (errno, message) = xxx_todo_changeme.args
     if errno != 2:  # ENOENT -- they don't have hg installed.
       raise
 
@@ -1254,7 +1257,8 @@ def GuessVCS(options):
                                               "--is-inside-work-tree"])
     if returncode == 0:
       return GitVCS(options)
-  except OSError, (errno, message):
+  except OSError as xxx_todo_changeme1:
+    (errno, message) = xxx_todo_changeme1.args
     if errno != 2:  # ENOENT -- they don't have git installed.
       raise
 
@@ -1301,12 +1305,12 @@ def RealMain(argv, data=None):
     data = vcs.GenerateDiff(args)
   files = vcs.GetBaseFiles(data)
   if verbosity >= 1:
-    print "Upload server:", options.server, "(change with -s/--server)"
+    print("Upload server:", options.server, "(change with -s/--server)")
   if options.issue:
     prompt = "Message describing this patch set: "
   else:
     prompt = "New issue subject: "
-  message = options.message or raw_input(prompt).strip()
+  message = options.message or input(prompt).strip()
   if not message:
     ErrorExit("A non-empty message is required")
   rpc_server = GetRpcServer(options)
@@ -1339,7 +1343,7 @@ def RealMain(argv, data=None):
   # Send a hash of all the base file so the server can determine if a copy
   # already exists in an earlier patchset.
   base_hashes = ""
-  for file, info in files.iteritems():
+  for file, info in files.items():
     if not info[0] is None:
       checksum = md5.new(info[0]).hexdigest()
       if base_hashes:
@@ -1353,7 +1357,7 @@ def RealMain(argv, data=None):
   if not options.download_base:
     form_fields.append(("content_upload", "1"))
   if len(data) > MAX_UPLOAD_SIZE:
-    print "Patch is large, so uploading file patches separately."
+    print("Patch is large, so uploading file patches separately.")
     uploaded_diff_file = []
     form_fields.append(("separate_patches", "1"))
   else:
@@ -1393,7 +1397,7 @@ def main():
   try:
     RealMain(sys.argv)
   except KeyboardInterrupt:
-    print
+    print()
     StatusUpdate("Interrupted.")
     sys.exit(1)
 
diff --git a/security/nss/gtests/google_test/gtest/test/googletest-env-var-test.py b/security/nss/gtests/google_test/gtest/test/googletest-env-var-test.py
index 02c3655c39..1eb3f9c8e7 100644
--- a/security/nss/gtests/google_test/gtest/test/googletest-env-var-test.py
+++ b/security/nss/gtests/google_test/gtest/test/googletest-env-var-test.py
@@ -31,6 +31,7 @@
 
 """Verifies that Google Test correctly parses environment variables."""
 
+from __future__ import print_function
 import os
 import gtest_test_utils
 
@@ -45,8 +46,8 @@ environ = os.environ.copy()
 
 def AssertEq(expected, actual):
   if expected != actual:
-    print('Expected: %s' % (expected,))
-    print('  Actual: %s' % (actual,))
+    print(('Expected: %s' % (expected,)))
+    print(('  Actual: %s' % (actual,)))
     raise AssertionError
 
 
diff --git a/security/nss/gtests/google_test/gtest/test/googletest-throw-on-failure-test.py b/security/nss/gtests/google_test/gtest/test/googletest-throw-on-failure-test.py
index ea627c479d..028e43ff3f 100644
--- a/security/nss/gtests/google_test/gtest/test/googletest-throw-on-failure-test.py
+++ b/security/nss/gtests/google_test/gtest/test/googletest-throw-on-failure-test.py
@@ -35,6 +35,7 @@ This script invokes googletest-throw-on-failure-test_ (a program written with
 Google Test) with different environments and command line flags.
 """
 
+from __future__ import print_function
 import os
 import gtest_test_utils
 
@@ -68,7 +69,7 @@ def SetEnvVar(env_var, value):
 def Run(command):
   """Runs a command; returns True/False if its exit code is/isn't 0."""
 
-  print('Running "%s". . .' % ' '.join(command))
+  print(('Running "%s". . .' % ' '.join(command)))
   p = gtest_test_utils.Subprocess(command)
   return p.exited and p.exit_code == 0
 
diff --git a/security/nss/gtests/google_test/gtest/test/googletest-uninitialized-test.py b/security/nss/gtests/google_test/gtest/test/googletest-uninitialized-test.py
index 69595a0dde..5b726cdda8 100644
--- a/security/nss/gtests/google_test/gtest/test/googletest-uninitialized-test.py
+++ b/security/nss/gtests/google_test/gtest/test/googletest-uninitialized-test.py
@@ -31,6 +31,7 @@
 
 """Verifies that Google Test warns the user when not initialized properly."""
 
+from __future__ import print_function
 import gtest_test_utils
 
 COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-uninitialized-test_')
@@ -43,8 +44,8 @@ def Assert(condition):
 
 def AssertEq(expected, actual):
   if expected != actual:
-    print('Expected: %s' % (expected,))
-    print('  Actual: %s' % (actual,))
+    print(('Expected: %s' % (expected,)))
+    print(('  Actual: %s' % (actual,)))
     raise AssertionError
 
 
diff --git a/security/nss/gtests/google_test/gtest/test/gtest_test_utils.py b/security/nss/gtests/google_test/gtest/test/gtest_test_utils.py
index d0c24466a4..3b73f136eb 100755
--- a/security/nss/gtests/google_test/gtest/test/gtest_test_utils.py
+++ b/security/nss/gtests/google_test/gtest/test/gtest_test_utils.py
@@ -31,6 +31,7 @@
 # Suppresses the 'Import not at the top of the file' lint complaint.
 # pylint: disable-msg=C6204
 
+from __future__ import print_function
 import os
 import sys
 
@@ -173,7 +174,7 @@ def GetTestExecutablePath(executable_name, build_dir=None):
         'Unable to find the test binary "%s". Please make sure to provide\n'
         'a path to the binary via the --build_dir flag or the BUILD_DIR\n'
         'environment variable.' % path)
-    print >> sys.stderr, message
+    print(message, file=sys.stderr)
     sys.exit(1)
 
   return path
diff --git a/security/nss/gtests/google_test/gtest/test/gtest_xml_test_utils.py b/security/nss/gtests/google_test/gtest/test/gtest_xml_test_utils.py
index ec42c62c3b..be5df6e0e5 100755
--- a/security/nss/gtests/google_test/gtest/test/gtest_xml_test_utils.py
+++ b/security/nss/gtests/google_test/gtest/test/gtest_xml_test_utils.py
@@ -74,8 +74,8 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
     self.assertEquals(
         expected_attributes.length, actual_attributes.length,
         'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % (
-            actual_node.tagName, expected_attributes.keys(),
-            actual_attributes.keys()))
+            actual_node.tagName, list(expected_attributes.keys()),
+            list(actual_attributes.keys())))
     for i in range(expected_attributes.length):
       expected_attr = expected_attributes.item(i)
       actual_attr = actual_attributes.get(expected_attr.name)
diff --git a/services/common/tests/mach_commands.py b/services/common/tests/mach_commands.py
index b57fa3aa26..ad016dbf3f 100644
--- a/services/common/tests/mach_commands.py
+++ b/services/common/tests/mach_commands.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import, unicode_literals
 
 import mozpack.path as mozpath
 
@@ -92,7 +91,7 @@ class SyncTestCommands(MachCommandBase):
             ]
 
         profile_dir = mkdtemp()
-        print 'Created profile directory: %s' % profile_dir
+        print('Created profile directory: %s' % profile_dir)
 
         try:
             env = {'XPCSHELL_TEST_PROFILE_DIR': profile_dir}
@@ -101,7 +100,7 @@ class SyncTestCommands(MachCommandBase):
             return proc.wait()
 
         finally:
-            print 'Removing profile directory %s' % profile_dir
+            print('Removing profile directory %s' % profile_dir)
             rmtree(profile_dir)
 
     @Command('storage-server', category='services',
diff --git a/taskcluster/taskgraph/create.py b/taskcluster/taskgraph/create.py
index f577f88731..e41d89fbdf 100644
--- a/taskcluster/taskgraph/create.py
+++ b/taskcluster/taskgraph/create.py
@@ -24,7 +24,7 @@ CONCURRENCY = 50
 
 
 def create_tasks(taskgraph, label_to_taskid, params):
-    taskid_to_label = {t: l for l, t in label_to_taskid.iteritems()}
+    taskid_to_label = {t: l for l, t in label_to_taskid.items()}
 
     session = requests.Session()
 
@@ -85,7 +85,7 @@ def create_tasks(taskgraph, label_to_taskid, params):
                                        taskid_to_label[task_id], task_def)
 
         # Wait for all futures to complete.
-        for f in futures.as_completed(fs.values()):
+        for f in futures.as_completed(list(fs.values())):
             f.result()
 
 
@@ -113,10 +113,10 @@ def resolve_timestamps(now, task_def):
         if isinstance(val, list):
             return [recurse(v) for v in val]
         elif isinstance(val, dict):
-            if val.keys() == ['relative-datestamp']:
+            if list(val.keys()) == ['relative-datestamp']:
                 return json_time_from_now(val['relative-datestamp'], now)
             else:
-                return {k: recurse(v) for k, v in val.iteritems()}
+                return {k: recurse(v) for k, v in val.items()}
         else:
             return val
     return recurse(task_def)
diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py
index d6460390fb..caba3442c7 100644
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -95,7 +95,7 @@ def taskgraph_decision(options):
     _, _ = TaskGraph.from_json(full_task_json)
 
     # write out the target task set to allow reproducing this as input
-    write_artifact('target-tasks.json', tgg.target_task_set.tasks.keys())
+    write_artifact('target-tasks.json', list(tgg.target_task_set.tasks.keys()))
 
     # write out the optimized task graph to describe what will actually happen,
     # and the map of labels to taskids
diff --git a/taskcluster/taskgraph/docker.py b/taskcluster/taskgraph/docker.py
index 8159fd5a4a..16b19dc02d 100644
--- a/taskcluster/taskgraph/docker.py
+++ b/taskcluster/taskgraph/docker.py
@@ -11,7 +11,7 @@ import os
 import subprocess
 import tarfile
 import tempfile
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import which
 
 from taskgraph.util import docker
@@ -28,7 +28,7 @@ def load_image_by_name(image_name):
 
     image_index_url = INDEX_URL.format('mozilla-central', image_name, context_hash)
     print("Fetching", image_index_url)
-    task = json.load(urllib2.urlopen(image_index_url))
+    task = json.load(six.moves.urllib.request.urlopen(image_index_url))
 
     return load_image_by_task_id(task['taskId'])
 
@@ -51,8 +51,8 @@ def load_image_by_task_id(task_id):
     print("Determining image name")
     tf = tarfile.open(filename)
     repositories = json.load(tf.extractfile('repositories'))
-    name = repositories.keys()[0]
-    tag = repositories[name].keys()[0]
+    name = list(repositories.keys())[0]
+    tag = list(repositories[name].keys())[0]
     name = '{}:{}'.format(name, tag)
     print("Image name:", name)
 
diff --git a/taskcluster/taskgraph/generator.py b/taskcluster/taskgraph/generator.py
index 809ed1f5c0..ec31625061 100644
--- a/taskcluster/taskgraph/generator.py
+++ b/taskcluster/taskgraph/generator.py
@@ -155,7 +155,7 @@ class TaskGraphGenerator(object):
         # in post-order
         kinds = {kind.name: kind for kind in self._load_kinds()}
         edges = set()
-        for kind in kinds.itervalues():
+        for kind in kinds.values():
             for dep in kind.config.get('kind-dependencies', []):
                 edges.add((kind.name, dep, 'kind-dependency'))
         kind_graph = Graph(set(kinds), edges)
@@ -211,7 +211,7 @@ class TaskGraphGenerator(object):
     def _run_until(self, name):
         while name not in self._run_results:
             try:
-                k, v = self._run.next()
+                k, v = next(self._run)
             except StopIteration:
                 raise AttributeError("No such run result {}".format(name))
             self._run_results[k] = v
diff --git a/taskcluster/taskgraph/optimize.py b/taskcluster/taskgraph/optimize.py
index 120e6807ba..855666c87b 100644
--- a/taskcluster/taskgraph/optimize.py
+++ b/taskcluster/taskgraph/optimize.py
@@ -51,10 +51,10 @@ def resolve_task_references(label, task_def, taskid_for_edge_name):
         if isinstance(val, list):
             return [recurse(v) for v in val]
         elif isinstance(val, dict):
-            if val.keys() == ['task-reference']:
+            if list(val.keys()) == ['task-reference']:
                 return TASK_REFERENCE_PATTERN.sub(repl, val['task-reference'])
             else:
-                return {k: recurse(v) for k, v in val.iteritems()}
+                return {k: recurse(v) for k, v in val.items()}
         else:
             return val
     return recurse(task_def)
@@ -78,7 +78,7 @@ def annotate_task_graph(target_task_graph, params, do_not_optimize,
         named_task_dependencies = named_links_dict.get(label, {})
 
         # check whether any dependencies have been optimized away
-        dependencies = [target_task_graph.tasks[l] for l in named_task_dependencies.itervalues()]
+        dependencies = [target_task_graph.tasks[l] for l in named_task_dependencies.values()]
         for t in dependencies:
             if t.optimized and not t.task_id:
                 raise Exception(
@@ -134,9 +134,9 @@ def get_subgraph(annotated_task_graph, named_links_dict, label_to_taskid):
         task.task_id = label_to_taskid[label] = slugid()
         named_task_dependencies = {
                 name: label_to_taskid[label]
-                for name, label in named_links_dict.get(label, {}).iteritems()}
+                for name, label in named_links_dict.get(label, {}.items())}
         task.task = resolve_task_references(task.label, task.task, named_task_dependencies)
-        task.task.setdefault('dependencies', []).extend(named_task_dependencies.itervalues())
+        task.task.setdefault('dependencies', []).extend(named_task_dependencies.values())
         tasks_by_taskid[task.task_id] = task
 
     # resolve edges to taskIds
diff --git a/taskcluster/taskgraph/target_tasks.py b/taskcluster/taskgraph/target_tasks.py
index d2b3f5a7f0..08a3f9c4ce 100644
--- a/taskcluster/taskgraph/target_tasks.py
+++ b/taskcluster/taskgraph/target_tasks.py
@@ -40,7 +40,7 @@ def target_tasks_try_option_syntax(full_task_graph, parameters):
     """Generate a list of target tasks based on try syntax in
     parameters['message'] and, for context, the full task graph."""
     options = try_option_syntax.TryOptionSyntax(parameters['message'], full_task_graph)
-    target_tasks_labels = [t.label for t in full_task_graph.tasks.itervalues()
+    target_tasks_labels = [t.label for t in full_task_graph.tasks.values()
                            if options.task_matches(t.attributes)]
 
     # If the developer wants test jobs to be rebuilt N times we add that value here
@@ -80,7 +80,7 @@ def target_tasks_default(full_task_graph, parameters):
             if project in RELEASE_PROJECTS:
                 return True
         return project in run_on_projects
-    return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)]
+    return [l for l, t in full_task_graph.tasks.items() if list(filter(t))]
 
 
 @_target_task('ash_tasks')
@@ -102,7 +102,7 @@ def target_tasks_ash(full_task_graph, parameters):
         if task.attributes['kind'] == 'upload-symbols':
             return False
         return True
-    return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)]
+    return [l for l, t in full_task_graph.tasks.items() if list(filter(t))]
 
 
 @_target_task('cedar_tasks')
@@ -118,4 +118,4 @@ def target_tasks_cedar(full_task_graph, parameters):
                     or 'xpcshell' in task.attributes['unittest_suite']):
                 return False
         return True
-    return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)]
+    return [l for l, t in full_task_graph.tasks.items() if list(filter(t))]
diff --git a/taskcluster/taskgraph/task/base.py b/taskcluster/taskgraph/task/base.py
index 2d9cbf5d95..d64d7198d3 100644
--- a/taskcluster/taskgraph/task/base.py
+++ b/taskcluster/taskgraph/task/base.py
@@ -5,9 +5,10 @@
 from __future__ import absolute_import, print_function, unicode_literals
 
 import abc
+import six
 
 
-class Task(object):
+class Task(six.with_metaclass(abc.ABCMeta, object)):
     """
     Representation of a task in a TaskGraph.  Each Task has, at creation:
 
@@ -26,7 +27,6 @@ class Task(object):
     path from which it draws its task configuration.  The instance is free to
     store as much local state as it needs.
     """
-    __metaclass__ = abc.ABCMeta
 
     def __init__(self, kind, label, attributes, task):
         self.kind = kind
diff --git a/taskcluster/taskgraph/task/docker_image.py b/taskcluster/taskgraph/task/docker_image.py
index fd67c48328..dd8a211b04 100644
--- a/taskcluster/taskgraph/task/docker_image.py
+++ b/taskcluster/taskgraph/task/docker_image.py
@@ -7,7 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
 import logging
 import json
 import os
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 
 from . import base
 from taskgraph.util.docker import (
@@ -16,6 +16,7 @@ from taskgraph.util.docker import (
     INDEX_PREFIX,
 )
 from taskgraph.util.templates import Templates
+import six
 
 logger = logging.getLogger(__name__)
 GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..'))
@@ -58,7 +59,7 @@ class DockerImageTask(base.Task):
 
         tasks = []
         templates = Templates(path)
-        for image_name, image_symbol in config['images'].iteritems():
+        for image_name, image_symbol in config['images'].items():
             context_path = os.path.join('testing', 'docker', image_name)
             context_hash = generate_context_hash(GECKO, context_path, image_name)
 
@@ -95,20 +96,20 @@ class DockerImageTask(base.Task):
         for index_path in self.index_paths:
             try:
                 url = INDEX_URL.format(index_path)
-                existing_task = json.load(urllib2.urlopen(url))
+                existing_task = json.load(six.moves.urllib.request.urlopen(url))
                 # Only return the task ID if the artifact exists for the indexed
                 # task.  Otherwise, continue on looking at each of the branches.  Method
                 # continues trying other branches in case mozilla-central has an expired
                 # artifact, but 'project' might not. Only return no task ID if all
                 # branches have been tried
-                request = urllib2.Request(
+                request = six.moves.urllib.request.Request(
                     ARTIFACT_URL.format(existing_task['taskId'], 'public/image.tar.zst'))
                 request.get_method = lambda: 'HEAD'
-                urllib2.urlopen(request)
+                six.moves.urllib.request.urlopen(request)
 
                 # HEAD success on the artifact is enough
                 return True, existing_task['taskId']
-            except urllib2.HTTPError:
+            except six.moves.urllib.error.HTTPError:
                 pass
 
         return False, None
diff --git a/taskcluster/taskgraph/task/signing.py b/taskcluster/taskgraph/task/signing.py
index a2a9ae3d66..6eff2ab751 100644
--- a/taskcluster/taskgraph/task/signing.py
+++ b/taskcluster/taskgraph/task/signing.py
@@ -33,7 +33,7 @@ class SigningTask(base.Task):
             templates = Templates(root)
             jobs = templates.load(filename, {})
 
-            for name, job in jobs.iteritems():
+            for name, job in jobs.items():
                 for artifact in job['unsigned-task']['artifacts']:
                     url = ARTIFACT_URL.format('<{}>'.format('unsigned-artifact'), artifact)
                     job['task']['payload']['unsignedArtifacts'].append({
diff --git a/taskcluster/taskgraph/task/test.py b/taskcluster/taskgraph/task/test.py
index 928f32a5a5..1309edcfbd 100644
--- a/taskcluster/taskgraph/task/test.py
+++ b/taskcluster/taskgraph/task/test.py
@@ -41,7 +41,7 @@ class TestTask(transform.TransformTask):
         test_descriptions = load_yaml(path, 'tests.yml')
 
         # generate all tests for all test platforms
-        for test_platform_name, test_platform in test_platforms.iteritems():
+        for test_platform_name, test_platform in test_platforms.items():
             for test_name in test_platform['test-names']:
                 test = copy.deepcopy(test_descriptions[test_name])
                 test['build-platform'] = test_platform['build-platform']
@@ -79,7 +79,7 @@ class TestTask(transform.TransformTask):
         based on the available build platforms.  Returns a dictionary mapping
         test platform to {test-set, build-platform, build-label}."""
         test_platforms = {}
-        for test_platform, cfg in test_platforms_cfg.iteritems():
+        for test_platform, cfg in test_platforms_cfg.items():
             build_platform = cfg['build-platform']
             if build_platform not in builds_by_platform:
                 logger.warning(
@@ -100,7 +100,7 @@ class TestTask(transform.TransformTask):
         `test-names` key for each test platform, containing a set of test
         names."""
         rv = {}
-        for test_platform, cfg in test_platforms.iteritems():
+        for test_platform, cfg in test_platforms.items():
             test_set = cfg['test-set']
             if test_set not in test_sets_cfg:
                 raise Exception(
diff --git a/taskcluster/taskgraph/task/transform.py b/taskcluster/taskgraph/task/transform.py
index 8183254a07..bc421f63be 100644
--- a/taskcluster/taskgraph/task/transform.py
+++ b/taskcluster/taskgraph/task/transform.py
@@ -48,9 +48,9 @@ class TransformTask(base.Task):
         """
         def jobs():
             defaults = config.get('job-defaults')
-            jobs = config.get('jobs', {}).iteritems()
+            jobs = config.get('jobs', {}.items())
             jobs_from = itertools.chain.from_iterable(
-                load_yaml(path, filename).iteritems()
+                load_yaml(path, filename.items())
                 for filename in config.get('jobs-from', {}))
             for name, job in itertools.chain(jobs, jobs_from):
                 if defaults:
diff --git a/taskcluster/taskgraph/taskgraph.py b/taskcluster/taskgraph/taskgraph.py
index 7736745ef5..0745588baa 100644
--- a/taskcluster/taskgraph/taskgraph.py
+++ b/taskcluster/taskgraph/taskgraph.py
@@ -52,7 +52,7 @@ class TaskGraph(object):
 
     def __iter__(self):
         "Iterate over tasks in undefined order"
-        return self.tasks.itervalues()
+        return self.tasks.values()
 
     def __repr__(self):
         return "".format(self.graph, self.tasks)
@@ -68,7 +68,7 @@ class TaskGraph(object):
         """
         tasks = {}
         edges = set()
-        for key, value in tasks_dict.iteritems():
+        for key, value in tasks_dict.items():
             # We get the implementation from JSON
             implementation = value['kind_implementation']
             # Loading the module and creating a Task from a dictionary
@@ -76,7 +76,7 @@ class TaskGraph(object):
             tasks[key] = task_kind.from_json(value)
             if 'task_id' in value:
                 tasks[key].task_id = value['task_id']
-            for depname, dep in value['dependencies'].iteritems():
+            for depname, dep in value['dependencies'].items():
                 edges.add((key, dep, depname))
         task_graph = cls(tasks, Graph(set(tasks), edges))
         return tasks, task_graph
diff --git a/taskcluster/taskgraph/test/test_create.py b/taskcluster/taskgraph/test/test_create.py
index b8da3aec0c..56ffee86f8 100644
--- a/taskcluster/taskgraph/test/test_create.py
+++ b/taskcluster/taskgraph/test/test_create.py
@@ -46,7 +46,7 @@ class TestCreate(unittest.TestCase):
 
         create.create_tasks(taskgraph, label_to_taskid, {'level': '4'})
 
-        for tid, task in self.created_tasks.iteritems():
+        for tid, task in self.created_tasks.items():
             self.assertEqual(task['payload'], 'hello world')
             self.assertEqual(task['schedulerId'], 'gecko-level-4')
             # make sure the dependencies exist, at least
@@ -68,7 +68,7 @@ class TestCreate(unittest.TestCase):
 
         create.create_tasks(taskgraph, label_to_taskid, {'level': '4'})
 
-        for tid, task in self.created_tasks.iteritems():
+        for tid, task in self.created_tasks.items():
             self.assertEqual(task.get('dependencies'), [os.environ['TASK_ID']])
 
 
diff --git a/taskcluster/taskgraph/test/test_generator.py b/taskcluster/taskgraph/test/test_generator.py
index f1b466e4dd..4c1fea0ef1 100644
--- a/taskcluster/taskgraph/test/test_generator.py
+++ b/taskcluster/taskgraph/test/test_generator.py
@@ -102,7 +102,7 @@ class TestGenerator(unittest.TestCase):
         self.tgg = self.maketgg(['fake-t-1'])
         self.assertEqual(self.tgg.target_task_set.graph,
                          graph.Graph({'fake-t-1'}, set()))
-        self.assertEqual(self.tgg.target_task_set.tasks.keys(),
+        self.assertEqual(list(self.tgg.target_task_set.tasks.keys()),
                          ['fake-t-1'])
 
     def test_target_task_graph(self):
diff --git a/taskcluster/taskgraph/test/test_optimize.py b/taskcluster/taskgraph/test/test_optimize.py
index 8d2ddf2478..702469b9df 100644
--- a/taskcluster/taskgraph/test/test_optimize.py
+++ b/taskcluster/taskgraph/test/test_optimize.py
@@ -79,7 +79,7 @@ class TestOptimize(unittest.TestCase):
         def repl(task_id):
             return 'SLUGID' if task_id and len(task_id) == 22 else task_id
         got_annotations = {
-            t.label: (t.optimized, repl(t.task_id)) for t in graph.tasks.itervalues()
+            t.label: (t.optimized, repl(t.task_id)) for t in graph.tasks.values()
         }
         self.assertEqual(got_annotations, annotations)
 
diff --git a/taskcluster/taskgraph/test/test_transforms_base.py b/taskcluster/taskgraph/test/test_transforms_base.py
index 0a0dfcaf29..6f14eeb6a8 100644
--- a/taskcluster/taskgraph/test/test_transforms_base.py
+++ b/taskcluster/taskgraph/test/test_transforms_base.py
@@ -15,7 +15,7 @@ from voluptuous import Schema
 
 schema = Schema({
     'x': int,
-    'y': basestring,
+    'y': str,
 })
 
 transforms = TransformSequence()
@@ -55,7 +55,7 @@ class TestValidateSchema(unittest.TestCase):
         try:
             validate_schema(schema, {'x': 'not-int'}, "pfx")
             self.fail("no exception raised")
-        except Exception, e:
+        except Exception as e:
             self.failUnless(str(e).startswith("pfx\n"))
 
 
diff --git a/taskcluster/taskgraph/test/test_try_option_syntax.py b/taskcluster/taskgraph/test/test_try_option_syntax.py
index 29aa2d5a90..0ed69c1ee7 100644
--- a/taskcluster/taskgraph/test/test_try_option_syntax.py
+++ b/taskcluster/taskgraph/test/test_try_option_syntax.py
@@ -40,9 +40,9 @@ tasks = {k: v for k, v in [
     unittest_task('gtest', 'linux64'),
     talos_task('dromaeojs', 'linux64'),
 ]}
-unittest_tasks = {k: v for k, v in tasks.iteritems()
+unittest_tasks = {k: v for k, v in tasks.items()
                   if 'unittest_try_name' in v.attributes}
-talos_tasks = {k: v for k, v in tasks.iteritems()
+talos_tasks = {k: v for k, v in tasks.items()
                if 'talos_try_name' in v.attributes}
 graph_with_jobs = TaskGraph(tasks, Graph(set(tasks), set()))
 
@@ -139,7 +139,7 @@ class TestTryOptionSyntax(unittest.TestCase):
         tos = TryOptionSyntax('try: -p linux,linux64', empty_graph)
         ridealongs = list(task
                           for task in itertools.chain.from_iterable(
-                                RIDEALONG_BUILDS.itervalues()
+                                RIDEALONG_BUILDS.values()
                           )
                           if 'android' not in task)  # Don't include android-l10n
         self.assertEqual(sorted(tos.platforms), sorted(['linux', 'linux64'] + ridealongs))
diff --git a/taskcluster/taskgraph/transforms/base.py b/taskcluster/taskgraph/transforms/base.py
index aab1392521..a52ebc5025 100644
--- a/taskcluster/taskgraph/transforms/base.py
+++ b/taskcluster/taskgraph/transforms/base.py
@@ -102,7 +102,7 @@ def get_keyed_by(item, field, item_name, subfield=None):
             return value
 
     assert len(value) == 1, "Invalid attribute {} in {}".format(field, item_name)
-    keyed_by = value.keys()[0]
+    keyed_by = list(value.keys())[0]
     values = value[keyed_by]
     if keyed_by.startswith('by-'):
         keyed_by = keyed_by[3:]  # extract just the keyed-by field name
diff --git a/taskcluster/taskgraph/transforms/job/__init__.py b/taskcluster/taskgraph/transforms/job/__init__.py
index a0860c0324..52a367e65f 100644
--- a/taskcluster/taskgraph/transforms/job/__init__.py
+++ b/taskcluster/taskgraph/transforms/job/__init__.py
@@ -28,15 +28,15 @@ logger = logging.getLogger(__name__)
 
 # Voluptuous uses marker objects as dictionary *keys*, but they are not
 # comparable, so we cast all of the keys back to regular strings
-task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()}
+task_description_schema = {str(k): v for k, v in task_description_schema.schema.items()}
 
 # Schema for a build description
 job_description_schema = Schema({
     # The name of the job and the job's label.  At least one must be specified,
     # and the label will be generated from the name if necessary, by prepending
     # the kind.
-    Optional('name'): basestring,
-    Optional('label'): basestring,
+    Optional('name'): str,
+    Optional('label'): str,
 
     # the following fields are passed directly through to the task description,
     # possibly modified by the run implementation.  See
@@ -59,7 +59,7 @@ job_description_schema = Schema({
     # A description of how to run this job.
     'run': {
         # The key to a job implementation in a peer module to this one
-        'using': basestring,
+        'using': str,
 
         # Any remaining content is verified against that job implementation's
         # own schema.
diff --git a/taskcluster/taskgraph/transforms/job/hazard.py b/taskcluster/taskgraph/transforms/job/hazard.py
index c5b500843d..66b2ea31bc 100644
--- a/taskcluster/taskgraph/transforms/job/hazard.py
+++ b/taskcluster/taskgraph/transforms/job/hazard.py
@@ -21,20 +21,20 @@ haz_run_schema = Schema({
     Required('using'): 'hazard',
 
     # The command to run within the task image (passed through to the worker)
-    Required('command'): basestring,
+    Required('command'): str,
 
     # The tooltool manifest to use; default in the script is used if omitted
-    Optional('tooltool-manifest'): basestring,
+    Optional('tooltool-manifest'): str,
 
     # The mozconfig to use; default in the script is used if omitted
-    Optional('mozconfig'): basestring,
+    Optional('mozconfig'): str,
 
     # The set of secret names to which the task has access; these are prefixed
     # with `project/releng/gecko/{treeherder.kind}/level-{level}/`.   Setting
     # this will enable any worker features required and set the task's scopes
     # appropriately.  `true` here means ['*'], all secrets.  Not supported on
     # Windows
-    Required('secrets', default=False): Any(bool, [basestring]),
+    Required('secrets', default=False): Any(bool, [str]),
 })
 
 
diff --git a/taskcluster/taskgraph/transforms/job/mach.py b/taskcluster/taskgraph/transforms/job/mach.py
index 8df202dbcc..74f8349b3d 100644
--- a/taskcluster/taskgraph/transforms/job/mach.py
+++ b/taskcluster/taskgraph/transforms/job/mach.py
@@ -15,7 +15,7 @@ mach_schema = Schema({
     Required('using'): 'mach',
 
     # The mach command (omitting `./mach`) to run
-    Required('mach'): basestring,
+    Required('mach'): str,
 })
 
 
diff --git a/taskcluster/taskgraph/transforms/job/mozharness.py b/taskcluster/taskgraph/transforms/job/mozharness.py
index fb3cd00dd8..f85acc2135 100644
--- a/taskcluster/taskgraph/transforms/job/mozharness.py
+++ b/taskcluster/taskgraph/transforms/job/mozharness.py
@@ -28,22 +28,22 @@ mozharness_run_schema = Schema({
 
     # the mozharness script used to run this task, relative to the testing/
     # directory and using forward slashes even on Windows
-    Required('script'): basestring,
+    Required('script'): str,
 
     # the config files required for the task, relative to
     # testing/mozharness/configs and using forward slashes even on Windows
-    Required('config'): [basestring],
+    Required('config'): [str],
 
     # any additional actions to pass to the mozharness command; not supported
     # on Windows
-    Optional('actions'): [basestring],
+    Optional('actions'): [str],
 
     # any additional options (without leading --) to be passed to mozharness;
     # not supported on Windows
-    Optional('options'): [basestring],
+    Optional('options'): [str],
 
     # --custom-build-variant-cfg value (not supported on Windows)
-    Optional('custom-build-variant-cfg'): basestring,
+    Optional('custom-build-variant-cfg'): str,
 
     # If not false, tooltool downloads will be enabled via relengAPIProxy
     # for either just public files, or all files.  Not supported on Windows
@@ -58,7 +58,7 @@ mozharness_run_schema = Schema({
     # this will enable any worker features required and set the task's scopes
     # appropriately.  `true` here means ['*'], all secrets.  Not supported on
     # Windows
-    Required('secrets', default=False): Any(bool, [basestring]),
+    Required('secrets', default=False): Any(bool, [str]),
 
     # If true, taskcluster proxy will be enabled; note that it may also be enabled
     # automatically e.g., for secrets support.  Not supported on Windows.
@@ -72,7 +72,7 @@ mozharness_run_schema = Schema({
     Required('keep-artifacts', default=True): bool,
 
     # If specified, use the in-tree job script specified.
-    Optional('job-script'): basestring,
+    Optional('job-script'): str,
 })
 
 
diff --git a/taskcluster/taskgraph/transforms/job/run_task.py b/taskcluster/taskgraph/transforms/job/run_task.py
index 296fe43eee..b035873147 100644
--- a/taskcluster/taskgraph/transforms/job/run_task.py
+++ b/taskcluster/taskgraph/transforms/job/run_task.py
@@ -28,7 +28,7 @@ run_task_schema = Schema({
     # The command arguments to pass to the `run-task` script, after the
     # checkout arguments.  If a list, it will be passed directly; otherwise
     # it will be included in a single argument to `bash -cx`.
-    Required('command'): Any([basestring], basestring),
+    Required('command'): Any([str], str),
 })
 
 
@@ -49,7 +49,7 @@ def docker_worker_run_task(config, job, taskdesc):
         })
 
     run_command = run['command']
-    if isinstance(run_command, basestring):
+    if isinstance(run_command, str):
         run_command = ['bash', '-cx', run_command]
     command = ['/home/worker/bin/run-task']
     if run['checkout']:
diff --git a/taskcluster/taskgraph/transforms/job/spidermonkey.py b/taskcluster/taskgraph/transforms/job/spidermonkey.py
index d78b785046..afac6e4f0f 100644
--- a/taskcluster/taskgraph/transforms/job/spidermonkey.py
+++ b/taskcluster/taskgraph/transforms/job/spidermonkey.py
@@ -19,11 +19,11 @@ sm_run_schema = Schema({
     Required('using'): Any('spidermonkey', 'spidermonkey-package', 'spidermonkey-mozjs-crate'),
 
     # The SPIDERMONKEY_VARIANT
-    Required('spidermonkey-variant'): basestring,
+    Required('spidermonkey-variant'): str,
 
     # The tooltool manifest to use; default from sm-tooltool-config.sh  is used
     # if omitted
-    Optional('tooltool-manifest'): basestring,
+    Optional('tooltool-manifest'): str,
 })
 
 
diff --git a/taskcluster/taskgraph/transforms/job/toolchain.py b/taskcluster/taskgraph/transforms/job/toolchain.py
index d814f78249..cad067f7ee 100644
--- a/taskcluster/taskgraph/transforms/job/toolchain.py
+++ b/taskcluster/taskgraph/transforms/job/toolchain.py
@@ -19,7 +19,7 @@ toolchain_run_schema = Schema({
     Required('using'): 'toolchain-script',
 
     # the script (in taskcluster/scripts/misc) to run
-    Required('script'): basestring,
+    Required('script'): str,
 })
 
 
diff --git a/taskcluster/taskgraph/transforms/l10n.py b/taskcluster/taskgraph/transforms/l10n.py
index 42137b5581..bb07858442 100644
--- a/taskcluster/taskgraph/transforms/l10n.py
+++ b/taskcluster/taskgraph/transforms/l10n.py
@@ -21,10 +21,7 @@ def mh_config_replace_project(config, jobs):
             # Nothing to do, not mozharness
             yield job
             continue
-        job['run']['config'] = map(
-            lambda x: x.format(project=config.params['project']),
-            job['run']['config']
-            )
+        job['run']['config'] = [x.format(project=config.params['project']) for x in job['run']['config']]
         yield job
 
 
@@ -37,8 +34,5 @@ def mh_options_replace_project(config, jobs):
             # Nothing to do, not mozharness
             yield job
             continue
-        job['run']['options'] = map(
-            lambda x: x.format(project=config.params['project']),
-            job['run']['options']
-            )
+        job['run']['options'] = [x.format(project=config.params['project']) for x in job['run']['options']]
         yield job
diff --git a/taskcluster/taskgraph/transforms/task.py b/taskcluster/taskgraph/transforms/task.py
index 6e371e4baa..d4d2cc08cf 100644
--- a/taskcluster/taskgraph/transforms/task.py
+++ b/taskcluster/taskgraph/transforms/task.py
@@ -24,40 +24,40 @@ from .gecko_v2_whitelist import JOB_NAME_WHITELIST, JOB_NAME_WHITELIST_ERROR
 
 # shortcut for a string where task references are allowed
 taskref_or_string = Any(
-    basestring,
-    {Required('task-reference'): basestring})
+    str,
+    {Required('task-reference'): str})
 
 # A task description is a general description of a TaskCluster task
 task_description_schema = Schema({
     # the label for this task
-    Required('label'): basestring,
+    Required('label'): str,
 
     # description of the task (for metadata)
-    Required('description'): basestring,
+    Required('description'): str,
 
     # attributes for this task
-    Optional('attributes'): {basestring: object},
+    Optional('attributes'): {str: object},
 
     # dependencies of this task, keyed by name; these are passed through
     # verbatim and subject to the interpretation of the Task's get_dependencies
     # method.
-    Optional('dependencies'): {basestring: object},
+    Optional('dependencies'): {str: object},
 
     # expiration and deadline times, relative to task creation, with units
     # (e.g., "14 days").  Defaults are set based on the project.
-    Optional('expires-after'): basestring,
-    Optional('deadline-after'): basestring,
+    Optional('expires-after'): str,
+    Optional('deadline-after'): str,
 
     # custom routes for this task; the default treeherder routes will be added
     # automatically
-    Optional('routes'): [basestring],
+    Optional('routes'): [str],
 
     # custom scopes for this task; any scopes required for the worker will be
     # added automatically
-    Optional('scopes'): [basestring],
+    Optional('scopes'): [str],
 
     # custom "task.extra" content
-    Optional('extra'): {basestring: object},
+    Optional('extra'): {str: object},
 
     # treeherder-related information; see
     # https://schemas.taskcluster.net/taskcluster-treeherder/v1/task-treeherder-config.json
@@ -65,7 +65,7 @@ task_description_schema = Schema({
     # added to the task
     Optional('treeherder'): {
         # either a bare symbol, or "grp(sym)".
-        'symbol': basestring,
+        'symbol': str,
 
         # the job kind
         'kind': Any('build', 'test', 'other'),
@@ -76,7 +76,7 @@ task_description_schema = Schema({
         # task platform, in the form platform/collection, used to set
         # treeherder.machine.platform and treeherder.collection or
         # treeherder.labels
-        'platform': basestring,
+        'platform': str,
 
         # treeherder environments (defaults to both staging and production)
         Required('environments', default=['production', 'staging']): ['production', 'staging'],
@@ -92,15 +92,15 @@ task_description_schema = Schema({
         'job-name': Any(
             # Assuming the job is named "normally", this is the v2 job name,
             # and the v1 and buildbot routes will be determined appropriately.
-            basestring,
+            str,
 
             # otherwise, give separate names for each of the legacy index
             # routes; if a name is omitted, no corresponding route will be
             # created.
             {
                 # the name as it appears in buildbot routes
-                Optional('buildbot'): basestring,
-                Required('gecko-v2'): basestring,
+                Optional('buildbot'): str,
+                Required('gecko-v2'): str,
             }
         ),
 
@@ -128,17 +128,17 @@ task_description_schema = Schema({
     # The `run_on_projects` attribute, defaulting to "all".  This dictates the
     # projects on which this task should be included in the target task set.
     # See the attributes documentation for details.
-    Optional('run-on-projects'): [basestring],
+    Optional('run-on-projects'): [str],
 
     # If the task can be coalesced, this is the name used in the coalesce key
     # the project, etc. will be added automatically.  Note that try (level 1)
     # tasks are never coalesced
-    Optional('coalesce-name'): basestring,
+    Optional('coalesce-name'): str,
 
     # the provisioner-id/worker-type for the task.  The following parameters will
     # be substituted in this string:
     #  {level} -- the scm level of this push
-    'worker-type': basestring,
+    'worker-type': str,
 
     # information specific to the worker implementation that will run this task
     'worker': Any({
@@ -150,9 +150,9 @@ task_description_schema = Schema({
         # generally `desktop-test`, or an image that acts an awful lot like it.
         Required('docker-image'): Any(
             # a raw Docker image path (repo/image:tag)
-            basestring,
+            str,
             # an in-tree generated docker image (from `testing/docker/`)
-            {'in-tree': basestring}
+            {'in-tree': str}
         ),
 
         # worker features that should be enabled
@@ -170,10 +170,10 @@ task_description_schema = Schema({
 
             # name of the cache, allowing re-use by subsequent tasks naming the
             # same cache
-            'name': basestring,
+            'name': str,
 
             # location in the task image where the cache will be mounted
-            'mount-point': basestring,
+            'mount-point': str,
         }],
 
         # artifacts to extract from the task image after completion
@@ -182,15 +182,15 @@ task_description_schema = Schema({
             'type': Any('file', 'directory'),
 
             # task image path from which to read artifact
-            'path': basestring,
+            'path': str,
 
             # name of the produced artifact (root of the names for
             # type=directory)
-            'name': basestring,
+            'name': str,
         }],
 
         # environment variables
-        Required('env', default={}): {basestring: taskref_or_string},
+        Required('env', default={}): {str: taskref_or_string},
 
         # the command to run
         'command': [taskref_or_string],
@@ -214,53 +214,53 @@ task_description_schema = Schema({
             'type': Any('file', 'directory'),
 
             # task image path from which to read artifact
-            'path': basestring,
+            'path': str,
         }],
 
         # directories and/or files to be mounted
         Optional('mounts'): [{
             # a unique name for the cache volume
-            'cache-name': basestring,
+            'cache-name': str,
 
             # task image path for the cache
-            'path': basestring,
+            'path': str,
         }],
 
         # environment variables
-        Required('env', default={}): {basestring: taskref_or_string},
+        Required('env', default={}): {str: taskref_or_string},
 
         # the maximum time to run, in seconds
         'max-run-time': int,
 
         # os user groups for test task workers
-        Optional('os-groups', default=[]): [basestring],
+        Optional('os-groups', default=[]): [str],
     }, {
         Required('implementation'): 'buildbot-bridge',
 
         # see
         # https://github.com/mozilla/buildbot-bridge/blob/master/bbb/schemas/payload.yml
-        'buildername': basestring,
+        'buildername': str,
         'sourcestamp': {
-            'branch': basestring,
-            Optional('revision'): basestring,
-            Optional('repository'): basestring,
-            Optional('project'): basestring,
+            'branch': str,
+            Optional('revision'): str,
+            Optional('repository'): str,
+            Optional('project'): str,
         },
         'properties': {
-            'product': basestring,
-            Extra: basestring,  # additional properties are allowed
+            'product': str,
+            Extra: str,  # additional properties are allowed
         },
     }, {
         'implementation': 'macosx-engine',
 
         # A link for an executable to download
-        Optional('link'): basestring,
+        Optional('link'): str,
 
         # the command to run
         Required('command'): [taskref_or_string],
 
         # environment variables
-        Optional('env'): {basestring: taskref_or_string},
+        Optional('env'): {str: taskref_or_string},
 
         # artifacts to extract from the task image after completion
         Optional('artifacts'): [{
@@ -268,11 +268,11 @@ task_description_schema = Schema({
             Required('type'): Any('file', 'directory'),
 
             # task image path from which to read artifact
-            Required('path'): basestring,
+            Required('path'): str,
 
             # name of the produced artifact (root of the names for
             # type=directory)
-            Required('name'): basestring,
+            Required('name'): str,
         }],
     }),
 
@@ -283,7 +283,7 @@ task_description_schema = Schema({
         # This task only needs to be run if a file matching one of the given
         # patterns has changed in the push.  The patterns use the mozpack
         # match function (python/mozbuild/mozpack/path.py).
-        Optional('files-changed'): [basestring],
+        Optional('files-changed'): [str],
     }),
 })
 
@@ -457,12 +457,12 @@ def build_generic_worker_payload(config, task, task_def):
 @payload_builder('macosx-engine')
 def build_macosx_engine_payload(config, task, task_def):
     worker = task['worker']
-    artifacts = map(lambda artifact: {
+    artifacts = [{
         'name': artifact['name'],
         'path': artifact['path'],
         'type': artifact['type'],
         'expires': task_def['expires'],
-    }, worker['artifacts'])
+    } for artifact in worker['artifacts']]
 
     task_def['payload'] = {
         'link': worker['link'],
@@ -494,7 +494,7 @@ def add_index_routes(config, tasks):
 
         job_name = index['job-name']
         # unpack the v2 name to v1 and buildbot names
-        if isinstance(job_name, basestring):
+        if isinstance(job_name, str):
             base_name, type_name = job_name.rsplit('-', 1)
             job_name = {
                 'buildbot': base_name,
diff --git a/taskcluster/taskgraph/transforms/tests/make_task_description.py b/taskcluster/taskgraph/transforms/tests/make_task_description.py
index fc3f948930..1e29558d6b 100644
--- a/taskcluster/taskgraph/transforms/tests/make_task_description.py
+++ b/taskcluster/taskgraph/transforms/tests/make_task_description.py
@@ -248,7 +248,7 @@ def docker_worker_setup(config, test, taskdesc):
         elif mozharness['chunking-args'] == 'test-suite-suffix':
             suffix = mozharness['chunk-suffix'].replace('', str(test['this-chunk']))
             for i, c in enumerate(command):
-                if isinstance(c, basestring) and c.startswith('--test-suite'):
+                if isinstance(c, str) and c.startswith('--test-suite'):
                     command[i] += suffix
 
     if 'download-symbols' in mozharness:
@@ -352,7 +352,7 @@ def generic_worker_setup(config, test, taskdesc):
     mh_command.extend(['--installer-url', installer_url])
     mh_command.extend(['--test-packages-url', test_packages_url])
     if mozharness.get('download-symbols'):
-        if isinstance(mozharness['download-symbols'], basestring):
+        if isinstance(mozharness['download-symbols'], str):
             mh_command.extend(['--download-symbols', mozharness['download-symbols']])
         else:
             mh_command.extend(['--download-symbols', 'true'])
@@ -366,7 +366,7 @@ def generic_worker_setup(config, test, taskdesc):
         elif mozharness['chunking-args'] == 'test-suite-suffix':
             suffix = mozharness['chunk-suffix'].replace('', str(test['this-chunk']))
             for i, c in enumerate(mh_command):
-                if isinstance(c, basestring) and c.startswith('--test-suite'):
+                if isinstance(c, str) and c.startswith('--test-suite'):
                     mh_command[i] += suffix
 
     worker['command'] = [
@@ -436,7 +436,7 @@ def macosx_engine_setup(config, test, taskdesc):
         elif mozharness['chunking-args'] == 'test-suite-suffix':
             suffix = mozharness['chunk-suffix'].replace('', str(test['this-chunk']))
             for i, c in enumerate(command):
-                if isinstance(c, basestring) and c.startswith('--test-suite'):
+                if isinstance(c, str) and c.startswith('--test-suite'):
                     command[i] += suffix
 
     if 'download-symbols' in mozharness:
diff --git a/taskcluster/taskgraph/transforms/tests/test_description.py b/taskcluster/taskgraph/transforms/tests/test_description.py
index 1365919fe3..293802f612 100644
--- a/taskcluster/taskgraph/transforms/tests/test_description.py
+++ b/taskcluster/taskgraph/transforms/tests/test_description.py
@@ -29,37 +29,37 @@ from voluptuous import (
 # *****WARNING*****
 test_description_schema = Schema({
     # description of the suite, for the task metadata
-    'description': basestring,
+    'description': str,
 
     # test suite name, or /
     Required('suite'): Any(
-        basestring,
-        {'by-test-platform': {basestring: basestring}},
+        str,
+        {'by-test-platform': {str: str}},
     ),
 
     # the name by which this test suite is addressed in try syntax; defaults to
     # the test-name
-    Optional('unittest-try-name'): basestring,
+    Optional('unittest-try-name'): str,
 
     # the symbol, or group(symbol), under which this task should appear in
     # treeherder.
-    'treeherder-symbol': basestring,
+    'treeherder-symbol': str,
 
     # the value to place in task.extra.treeherder.machine.platform; ideally
     # this is the same as build-platform, and that is the default, but in
     # practice it's not always a match.
-    Optional('treeherder-machine-platform'): basestring,
+    Optional('treeherder-machine-platform'): str,
 
     # attributes to appear in the resulting task (later transforms will add the
     # common attributes)
-    Optional('attributes'): {basestring: object},
+    Optional('attributes'): {str: object},
 
     # The `run_on_projects` attribute, defaulting to "all".  This dictates the
     # projects on which this task should be included in the target task set.
     # See the attributes documentation for details.
     Optional('run-on-projects', default=['all']): Any(
-        [basestring],
-        {'by-test-platform': {basestring: [basestring]}},
+        [str],
+        {'by-test-platform': {str: [str]}},
     ),
 
     # the sheriffing tier for this task (default: set based on test platform)
@@ -70,12 +70,12 @@ test_description_schema = Schema({
     # test platform is not found, the key 'default' will be tried.
     Required('chunks', default=1): Any(
         int,
-        {'by-test-platform': {basestring: int}},
+        {'by-test-platform': {str: int}},
     ),
 
     # the time (with unit) after which this task is deleted; default depends on
     # the branch (see below)
-    Optional('expires-after'): basestring,
+    Optional('expires-after'): str,
 
     # Whether to run this task with e10s (desktop-test only).  If false, run
     # without e10s; if true, run with e10s; if 'both', run one task with and
@@ -83,13 +83,13 @@ test_description_schema = Schema({
     # and treeherder group.
     Required('e10s', default='both'): Any(
         bool, 'both',
-        {'by-test-platform': {basestring: Any(bool, 'both')}},
+        {'by-test-platform': {str: Any(bool, 'both')}},
     ),
 
     # The EC2 instance size to run these tests on.
     Required('instance-size', default='default'): Any(
         Any('default', 'large', 'xlarge', 'legacy'),
-        {'by-test-platform': {basestring: Any('default', 'large', 'xlarge', 'legacy')}},
+        {'by-test-platform': {str: Any('default', 'large', 'xlarge', 'legacy')}},
     ),
 
     # Whether the task requires loopback audio or video (whatever that may mean
@@ -119,16 +119,16 @@ test_description_schema = Schema({
     # generally `desktop-test`, or an image that acts an awful lot like it.
     Required('docker-image', default={'in-tree': 'desktop-test'}): Any(
         # a raw Docker image path (repo/image:tag)
-        basestring,
+        str,
         # an in-tree generated docker image (from `testing/docker/`)
-        {'in-tree': basestring}
+        {'in-tree': str}
     ),
 
     # seconds of runtime after which the task will be killed.  Like 'chunks',
     # this can be keyed by test pltaform.
     Required('max-run-time', default=3600): Any(
         int,
-        {'by-test-platform': {basestring: int}},
+        {'by-test-platform': {str: int}},
     ),
 
     # the exit status code that indicates the task should be retried
@@ -140,27 +140,27 @@ test_description_schema = Schema({
     # What to run
     Required('mozharness'): Any({
         # the mozharness script used to run this task
-        Required('script'): basestring,
+        Required('script'): str,
 
         # the config files required for the task
         Required('config'): Any(
-            [basestring],
-            {'by-test-platform': {basestring: [basestring]}},
+            [str],
+            {'by-test-platform': {str: [str]}},
         ),
 
         # any additional actions to pass to the mozharness command
-        Optional('actions'): [basestring],
+        Optional('actions'): [str],
 
         # additional command-line options for mozharness, beyond those
         # automatically added
         Required('extra-options', default=[]): Any(
-            [basestring],
-            {'by-test-platform': {basestring: [basestring]}},
+            [str],
+            {'by-test-platform': {str: [str]}},
         ),
 
         # the artifact name (including path) to test on the build task; this is
         # generally set in a per-kind transformation
-        Optional('build-artifact-name'): basestring,
+        Optional('build-artifact-name'): str,
 
         # If true, tooltool downloads will be enabled via relengAPIProxy.
         Required('tooltool-downloads', default=False): bool,
@@ -197,7 +197,7 @@ test_description_schema = Schema({
         # the string to append to the `--test-suite` arugment when
         # chunking-args = test-suite-suffix; "" in this string will
         # be replaced with the chunk number.
-        Optional('chunk-suffix'): basestring,
+        Optional('chunk-suffix'): str,
     }),
 
     # The current chunk; this is filled in by `all_kinds.py`
@@ -206,24 +206,24 @@ test_description_schema = Schema({
     # os user groups for test task workers; required scopes, will be
     # added automatically
     Optional('os-groups', default=[]): Any(
-        [basestring],
+        [str],
         # todo: create a dedicated elevated worker group and name here
-        {'by-test-platform': {basestring: [basestring]}},
+        {'by-test-platform': {str: [str]}},
     ),
 
     # -- values supplied by the task-generation infrastructure
 
     # the platform of the build this task is testing
-    'build-platform': basestring,
+    'build-platform': str,
 
     # the label of the build task generating the materials to test
-    'build-label': basestring,
+    'build-label': str,
 
     # the platform on which the tests will run
-    'test-platform': basestring,
+    'test-platform': str,
 
     # the name of the test (the key in tests.yml)
-    'test-name': basestring,
+    'test-name': str,
 
 }, required=True)
 
diff --git a/taskcluster/taskgraph/try_option_syntax.py b/taskcluster/taskgraph/try_option_syntax.py
index b5988db981..609a7c0d23 100644
--- a/taskcluster/taskgraph/try_option_syntax.py
+++ b/taskcluster/taskgraph/try_option_syntax.py
@@ -259,8 +259,8 @@ class TryOptionSyntax(object):
     def parse_build_types(self, build_types_arg):
         if build_types_arg is None:
             build_types_arg = []
-        build_types = filter(None, [BUILD_TYPE_ALIASES.get(build_type) for
-                             build_type in build_types_arg])
+        build_types = [_f for _f in [BUILD_TYPE_ALIASES.get(build_type) for
+                             build_type in build_types_arg] if _f]
         return build_types
 
     def parse_platforms(self, platform_arg):
@@ -294,7 +294,7 @@ class TryOptionSyntax(object):
             return []
 
         all_platforms = set(t.attributes['test_platform']
-                            for t in full_task_graph.tasks.itervalues()
+                            for t in full_task_graph.tasks.values()
                             if 'test_platform' in t.attributes)
 
         tests = self.parse_test_opts(test_arg, all_platforms)
@@ -303,7 +303,7 @@ class TryOptionSyntax(object):
             return []
 
         all_tests = set(t.attributes[attr_name]
-                        for t in full_task_graph.tasks.itervalues()
+                        for t in full_task_graph.tasks.values()
                         if attr_name in t.attributes)
 
         # Special case where tests is 'all' and must be expanded
@@ -455,12 +455,12 @@ class TryOptionSyntax(object):
                 results.extend(self.handle_alias(test, all_tests))
 
         # uniquify the results over the test names
-        results = {test['test']: test for test in results}.values()
+        results = list({test['test']: test for test in results}.values())
         return results
 
     def find_all_attribute_suffixes(self, graph, prefix):
         rv = set()
-        for t in graph.tasks.itervalues():
+        for t in graph.tasks.values():
             for a in t.attributes:
                 if a.startswith(prefix):
                     rv.add(a[len(prefix):])
diff --git a/taskcluster/taskgraph/util/attributes.py b/taskcluster/taskgraph/util/attributes.py
index b44a3364f1..8a37392d63 100644
--- a/taskcluster/taskgraph/util/attributes.py
+++ b/taskcluster/taskgraph/util/attributes.py
@@ -11,7 +11,7 @@ def attrmatch(attributes, **kwargs):
     must be in the set.  A callable is called with the attribute value.  If an
     attribute is specified as a keyword argument but not present in the
     attributes, the result is False."""
-    for kwkey, kwval in kwargs.iteritems():
+    for kwkey, kwval in kwargs.items():
         if kwkey not in attributes:
             return False
         attval = attributes[kwkey]
diff --git a/taskcluster/taskgraph/util/seta.py b/taskcluster/taskgraph/util/seta.py
index a0cd30675a..f18083790d 100644
--- a/taskcluster/taskgraph/util/seta.py
+++ b/taskcluster/taskgraph/util/seta.py
@@ -43,7 +43,7 @@ class SETA(object):
                              kwargs={'timeout': 5, 'headers': headers})
             task_list = json.loads(response.content).get('jobtypes', '')
             if len(task_list) > 0:
-                low_value_tasks = task_list.values()[0]
+                low_value_tasks = list(task_list.values())[0]
 
             # Bug 1315145, disable SETA for tier-1 platforms until backfill is implemented.
             low_value_tasks = [x for x in low_value_tasks if x.find('debug') == -1]
diff --git a/testing/docker/funsize-update-generator/scripts/funsize.py b/testing/docker/funsize-update-generator/scripts/funsize.py
index fd591817c1..3068de5b36 100755
--- a/testing/docker/funsize-update-generator/scripts/funsize.py
+++ b/testing/docker/funsize-update-generator/scripts/funsize.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-import ConfigParser
+import six.moves.configparser
 import argparse
 import functools
 import hashlib
@@ -83,7 +83,7 @@ def get_option(directory, filename, section, option):
     log.debug("Exctracting [%s]: %s from %s/**/%s", section, option, directory,
               filename)
     f = find_file(directory, filename)
-    config = ConfigParser.ConfigParser()
+    config = six.moves.configparser.ConfigParser()
     config.read(f)
     rv = config.get(section, option)
     log.debug("Found %s", rv)
diff --git a/testing/docker/recipes/tooltool.py b/testing/docker/recipes/tooltool.py
index 952f9a5a7f..ed75536800 100755
--- a/testing/docker/recipes/tooltool.py
+++ b/testing/docker/recipes/tooltool.py
@@ -22,8 +22,9 @@
 # in which the manifest file resides and it should be called
 # 'manifest.tt'
 
+from __future__ import print_function
 import hashlib
-import httplib
+import six.moves.http_client
 import json
 import logging
 import optparse
@@ -34,12 +35,13 @@ import tarfile
 import tempfile
 import threading
 import time
-import urllib2
-import urlparse
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
+import six.moves.urllib.parse
 import zipfile
 
 from subprocess import PIPE
 from subprocess import Popen
+import six
 
 __version__ = '1'
 
@@ -308,7 +310,7 @@ class Manifest(object):
             rv = json.dump(
                 self.file_records, output_file, indent=0, cls=FileRecordJSONEncoder,
                 separators=(',', ': '))
-            print >> output_file, ''
+            print('', file=output_file)
             return rv
 
     def dumps(self, fmt='json'):
@@ -367,9 +369,9 @@ def list_manifest(manifest_file):
         ))
         return False
     for f in manifest.file_records:
-        print "%s\t%s\t%s" % ("P" if f.present() else "-",
+        print("%s\t%s\t%s" % ("P" if f.present() else "-",
                               "V" if f.present() and f.validate() else "-",
-                              f.filename)
+                              f.filename))
     return True
 
 
@@ -460,7 +462,7 @@ def fetch_file(base_urls, file_record, grabchunk=1024 * 4, auth_file=None, regio
     fetched_path = None
     for base_url in base_urls:
         # Generate the URL for the file on the server side
-        url = urlparse.urljoin(base_url,
+        url = six.moves.urllib.parse.urljoin(base_url,
                                '%s/%s' % (file_record.algorithm, file_record.digest))
         if region is not None:
             url += '?region=' + region
@@ -469,9 +471,9 @@ def fetch_file(base_urls, file_record, grabchunk=1024 * 4, auth_file=None, regio
 
         # Well, the file doesn't exist locally.  Let's fetch it.
         try:
-            req = urllib2.Request(url)
+            req = six.moves.urllib.request.Request(url)
             _authorize(req, auth_file)
-            f = urllib2.urlopen(req)
+            f = six.moves.urllib.request.urlopen(req)
             log.debug("opened %s for reading" % url)
             with open(temp_path, 'wb') as out:
                 k = True
@@ -488,7 +490,7 @@ def fetch_file(base_urls, file_record, grabchunk=1024 * 4, auth_file=None, regio
                          (file_record.filename, base_url, temp_path))
                 fetched_path = temp_path
                 break
-        except (urllib2.URLError, urllib2.HTTPError, ValueError) as e:
+        except (six.moves.urllib.error.URLError, six.moves.urllib.error.HTTPError, ValueError) as e:
             log.info("...failed to fetch '%s' from %s" %
                      (file_record.filename, base_url))
             log.debug("%s" % e)
@@ -668,7 +670,7 @@ def fetch_files(manifest_file, base_urls, filenames=[], cache_folder=None,
                 try:
                     if not os.path.exists(cache_folder):
                         log.info("Creating cache in %s..." % cache_folder)
-                        os.makedirs(cache_folder, 0700)
+                        os.makedirs(cache_folder, 0o700)
                     shutil.copy(os.path.join(os.getcwd(), localfile.filename),
                                 os.path.join(cache_folder, localfile.digest))
                     log.info("Local cache %s updated with %s" % (cache_folder,
@@ -759,14 +761,14 @@ def _authorize(req, auth_file):
 
 
 def _send_batch(base_url, auth_file, batch, region):
-    url = urlparse.urljoin(base_url, 'upload')
+    url = six.moves.urllib.parse.urljoin(base_url, 'upload')
     if region is not None:
         url += "?region=" + region
-    req = urllib2.Request(url, json.dumps(batch), {'Content-Type': 'application/json'})
+    req = six.moves.urllib.request.Request(url, json.dumps(batch), {'Content-Type': 'application/json'})
     _authorize(req, auth_file)
     try:
-        resp = urllib2.urlopen(req)
-    except (urllib2.URLError, urllib2.HTTPError) as e:
+        resp = six.moves.urllib.request.urlopen(req)
+    except (six.moves.urllib.error.URLError, six.moves.urllib.error.HTTPError) as e:
         _log_api_error(e)
         return None
     return json.load(resp)['result']
@@ -774,8 +776,8 @@ def _send_batch(base_url, auth_file, batch, region):
 
 def _s3_upload(filename, file):
     # urllib2 does not support streaming, so we fall back to good old httplib
-    url = urlparse.urlparse(file['put_url'])
-    cls = httplib.HTTPSConnection if url.scheme == 'https' else httplib.HTTPConnection
+    url = six.moves.urllib.parse.urlparse(file['put_url'])
+    cls = six.moves.http_client.HTTPSConnection if url.scheme == 'https' else six.moves.http_client.HTTPConnection
     host, port = url.netloc.split(':') if ':' in url.netloc else (url.netloc, 443)
     port = int(port)
     conn = cls(host, port)
@@ -797,14 +799,14 @@ def _s3_upload(filename, file):
 
 
 def _notify_upload_complete(base_url, auth_file, file):
-    req = urllib2.Request(
-        urlparse.urljoin(
+    req = six.moves.urllib.request.Request(
+        six.moves.urllib.parse.urljoin(
             base_url,
             'upload/complete/%(algorithm)s/%(digest)s' % file))
     _authorize(req, auth_file)
     try:
-        urllib2.urlopen(req)
-    except urllib2.HTTPError as e:
+        six.moves.urllib.request.urlopen(req)
+    except six.moves.urllib.error.HTTPError as e:
         if e.code != 409:
             _log_api_error(e)
             return
@@ -855,7 +857,7 @@ def upload(manifest, message, base_urls, auth_file, region):
     # Upload the files, each in a thread.  This allows us to start all of the
     # uploads before any of the URLs expire.
     threads = {}
-    for filename, file in files.iteritems():
+    for filename, file in files.items():
         if 'put_url' in file:
             log.info("%s: starting upload" % (filename,))
             thd = threading.Thread(target=_s3_upload,
@@ -885,7 +887,7 @@ def upload(manifest, message, base_urls, auth_file, region):
     # notify the server that the uploads are completed.  If the notification
     # fails, we don't consider that an error (the server will notice
     # eventually)
-    for filename, file in files.iteritems():
+    for filename, file in files.items():
         if 'put_url' in file and file['upload_ok']:
             log.info("notifying server of upload completion for %s" % (filename,))
             _notify_upload_complete(base_urls[0], auth_file, file)
diff --git a/testing/docker/rust-build/repack_rust.py b/testing/docker/rust-build/repack_rust.py
index e0a5e89c5f..bad93db043 100644
--- a/testing/docker/rust-build/repack_rust.py
+++ b/testing/docker/rust-build/repack_rust.py
@@ -5,6 +5,7 @@ with the necessary tool and target support for the Firefox
 build environment.
 '''
 
+from __future__ import print_function
 import os.path
 import requests
 import subprocess
@@ -24,12 +25,12 @@ def fetch_file(url):
 def fetch(url):
   '''Download and verify a package url.'''
   base = os.path.basename(url)
-  print('Fetching %s...' % base)
+  print(('Fetching %s...' % base))
   fetch_file(url + '.asc')
   fetch_file(url)
   fetch_file(url + '.sha256')
   fetch_file(url + '.asc.sha256')
-  print('Verifying %s...' % base)
+  print(('Verifying %s...' % base))
   subprocess.check_call(['shasum', '-c', base + '.sha256'])
   subprocess.check_call(['shasum', '-c', base + '.asc.sha256'])
   subprocess.check_call(['gpg', '--verify', base + '.asc', base])
@@ -40,15 +41,15 @@ def fetch(url):
 
 def install(filename, target):
   '''Run a package's installer script against the given target directory.'''
-  print(' Unpacking %s...' % filename)
+  print((' Unpacking %s...' % filename))
   subprocess.check_call(['tar', 'xf', filename])
   basename = filename.split('.tar')[0]
-  print(' Installing %s...' % basename)
+  print((' Installing %s...' % basename))
   install_cmd = [os.path.join(basename, 'install.sh')]
   install_cmd += ['--prefix=' + os.path.abspath(target)]
   install_cmd += ['--disable-ldconfig']
   subprocess.check_call(install_cmd)
-  print(' Cleaning %s...' % basename)
+  print((' Cleaning %s...' % basename))
   subprocess.check_call(['rm', '-rf', basename])
 
 def package(manifest, pkg, target):
@@ -60,9 +61,9 @@ def package(manifest, pkg, target):
 
 def fetch_package(manifest, pkg, host):
   version, info = package(manifest, pkg, host)
-  print('%s %s\n  %s\n  %s' % (pkg, version, info['url'], info['hash']))
+  print(('%s %s\n  %s\n  %s' % (pkg, version, info['url'], info['hash'])))
   if not info['available']:
-    print('%s marked unavailable for %s' % (pkg, host))
+    print(('%s marked unavailable for %s' % (pkg, host)))
     raise AssertionError
   fetch(info['url'])
   return info
@@ -84,15 +85,15 @@ def tar_for_host(host):
   return tar_options, tar_ext
 
 def repack(host, targets, channel='stable', suffix=''):
-  print("Repacking rust for %s..." % host)
+  print(("Repacking rust for %s..." % host))
   url = 'https://static.rust-lang.org/dist/channel-rust-' + channel + '.toml'
   req = requests.get(url)
   req.raise_for_status()
   manifest = toml.loads(req.content)
   if manifest['manifest-version'] != '2':
-    print('ERROR: unrecognized manifest version %s.' % manifest['manifest-version'])
+    print(('ERROR: unrecognized manifest version %s.' % manifest['manifest-version']))
     return
-  print('Using manifest for rust %s as of %s.' % (channel, manifest['date']))
+  print(('Using manifest for rust %s as of %s.' % (channel, manifest['date'])))
   print('Fetching packages...')
   rustc = fetch_package(manifest, 'rustc', host)
   cargo = fetch_package(manifest, 'cargo', host)
@@ -109,13 +110,13 @@ def repack(host, targets, channel='stable', suffix=''):
   for std in stds:
     install(os.path.basename(std['url']), install_dir)
     pass
-  print('Tarring %s...' % tar_basename)
+  print(('Tarring %s...' % tar_basename))
   tar_options, tar_ext = tar_for_host(host)
   subprocess.check_call(['tar', tar_options, tar_basename + tar_ext, install_dir])
   subprocess.check_call(['rm', '-rf', install_dir])
 
 def repack_cargo(host, channel='nightly'):
-  print("Repacking cargo for %s..." % host)
+  print(("Repacking cargo for %s..." % host))
   # Cargo doesn't seem to have a .toml manifest.
   base_url = 'https://static.rust-lang.org/cargo-dist/'
   req = requests.get(os.path.join(base_url, 'channel-cargo-' + channel))
@@ -125,7 +126,7 @@ def repack_cargo(host, channel='nightly'):
       if line.find(host) != -1:
           file = line.strip()
   if not file:
-      print('No manifest entry for %s!' % host)
+      print(('No manifest entry for %s!' % host))
       return
   manifest = {
           'date': req.headers['Last-Modified'],
@@ -142,7 +143,7 @@ def repack_cargo(host, channel='nightly'):
               },
           },
   }
-  print('Using manifest for cargo %s.' % channel)
+  print(('Using manifest for cargo %s.' % channel))
   print('Fetching packages...')
   cargo = fetch_package(manifest, 'cargo', host)
   print('Installing packages...')
@@ -150,7 +151,7 @@ def repack_cargo(host, channel='nightly'):
   subprocess.check_call(['rm', '-rf', install_dir])
   install(os.path.basename(cargo['url']), install_dir)
   tar_basename = 'cargo-%s-repack' % host
-  print('Tarring %s...' % tar_basename)
+  print(('Tarring %s...' % tar_basename))
   tar_options, tar_ext = tar_for_host(host)
   subprocess.check_call(['tar', tar_options, tar_basename + tar_ext, install_dir])
   subprocess.check_call(['rm', '-rf', install_dir])
diff --git a/testing/docker/rust-build/tcbuild.py b/testing/docker/rust-build/tcbuild.py
index d55c6f3a75..cf76482858 100644
--- a/testing/docker/rust-build/tcbuild.py
+++ b/testing/docker/rust-build/tcbuild.py
@@ -35,7 +35,7 @@ def read_tc_auth(tc_auth_file):
 
 def fill_template_dict(d, keys):
     for key, val in d.items():
-        if isinstance(val, basestring) and '{' in val:
+        if isinstance(val, str) and '{' in val:
             d[key] = val.format(**keys)
         elif isinstance(val, dict):
             fill_template_dict(val, keys)
diff --git a/testing/gtest/rungtests.py b/testing/gtest/rungtests.py
index 4999086800..e60d8d1fd7 100644
--- a/testing/gtest/rungtests.py
+++ b/testing/gtest/rungtests.py
@@ -6,6 +6,7 @@
 
 from __future__ import with_statement
 
+from __future__ import print_function
 from optparse import OptionParser
 import os
 import sys
@@ -172,13 +173,13 @@ def main():
     parser = gtestOptions()
     options, args = parser.parse_args()
     if not args:
-        print >>sys.stderr, """Usage: %s """ % sys.argv[0]
+        print("""Usage: %s """ % sys.argv[0], file=sys.stderr)
         sys.exit(1)
     if not options.xre_path:
-        print >>sys.stderr, """Error: --xre-path is required"""
+        print("""Error: --xre-path is required""", file=sys.stderr)
         sys.exit(1)
     if not options.utility_path:
-        print >>sys.stderr, """Warning: --utility-path is required to process assertion stacks"""
+        print("""Warning: --utility-path is required to process assertion stacks""", file=sys.stderr)
 
     update_mozinfo()
     prog = os.path.abspath(args[0])
@@ -189,7 +190,7 @@ def main():
                                   options.cwd,
                                   symbols_path=options.symbols_path,
                                   utility_path=options.utility_path)
-    except Exception, e:
+    except Exception as e:
         log.error(str(e))
         result = False
     sys.exit(0 if result else 1)
diff --git a/testing/mach_commands.py b/testing/mach_commands.py
index a744b0c44f..37090bb728 100644
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -482,13 +482,13 @@ class PushToTry(MachCommandBase):
         rv = defaultdict(list)
         for item in items:
             parsed = parse_arg(item)
-            for key, values in parsed.iteritems():
+            for key, values in parsed.items():
                 rv[key].extend(values)
 
         if not allow_subitems:
-            if not all(item == [] for item in rv.itervalues()):
+            if not all(item == [] for item in rv.values()):
                 raise ValueError("Unexpected subitems in argument")
-            return rv.keys()
+            return list(rv.keys())
         else:
             return rv
 
@@ -616,7 +616,7 @@ class PushToTry(MachCommandBase):
                 print("No saved configuration called %s found in autotry.ini" % kwargs["load"],
                       file=sys.stderr)
 
-            for key, value in kwargs.iteritems():
+            for key, value in kwargs.items():
                 if value in (None, []) and key in defaults:
                     kwargs[key] = defaults[key]
 
@@ -653,7 +653,7 @@ class PushToTry(MachCommandBase):
 
         if kwargs["verbose"] and paths_by_flavor:
             print('The following tests will be selected: ')
-            for flavor, paths in paths_by_flavor.iteritems():
+            for flavor, paths in paths_by_flavor.items():
                 print("%s: %s" % (flavor, ",".join(paths)))
 
         if kwargs["verbose"] or not kwargs["push"]:
diff --git a/testing/mochitest/mach_commands.py b/testing/mochitest/mach_commands.py
index a667c05488..51ca667d32 100644
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -4,6 +4,7 @@
 
 from __future__ import absolute_import, unicode_literals
 
+from __future__ import print_function
 from argparse import Namespace
 from collections import defaultdict
 from itertools import chain
@@ -305,14 +306,14 @@ class MachCommands(MachCommandBase):
 
         flavors = None
         if flavor:
-            for fname, fobj in ALL_FLAVORS.iteritems():
+            for fname, fobj in ALL_FLAVORS.items():
                 if flavor in fobj['aliases']:
                     if buildapp not in fobj['enabled_apps']:
                         continue
                     flavors = [fname]
                     break
         else:
-            flavors = [f for f, v in ALL_FLAVORS.iteritems() if buildapp in v['enabled_apps']]
+            flavors = [f for f, v in ALL_FLAVORS.items() if buildapp in v['enabled_apps']]
 
         from mozbuild.controller.building import BuildDriver
         self._ensure_state_subdir_exists('.')
@@ -376,8 +377,8 @@ class MachCommands(MachCommandBase):
         if not suites:
             # Make it very clear why no tests were found
             if not unsupported:
-                print(TESTS_NOT_FOUND.format('\n'.join(
-                    sorted(list(test_paths or test_objects)))))
+                print((TESTS_NOT_FOUND.format('\n'.join(
+                    sorted(list(test_paths or test_objects))))))
                 return 1
 
             msg = []
@@ -393,8 +394,8 @@ class MachCommands(MachCommandBase):
                 else:
                     reason = 'excluded by the command line'
                 msg.append('    mochitest -f {} ({})'.format(name, reason))
-            print(SUPPORTED_TESTS_NOT_FOUND.format(
-                buildapp, '\n'.join(sorted(msg))))
+            print((SUPPORTED_TESTS_NOT_FOUND.format(
+                buildapp, '\n'.join(sorted(msg)))))
             return 1
 
         if buildapp == 'android':
@@ -410,7 +411,7 @@ class MachCommands(MachCommandBase):
             msg = fobj['aliases'][0]
             if subsuite:
                 msg = '{} with subsuite {}'.format(msg, subsuite)
-            print(NOW_RUNNING.format(msg))
+            print((NOW_RUNNING.format(msg)))
 
             harness_args = kwargs.copy()
             harness_args['subsuite'] = subsuite
diff --git a/testing/mochitest/mach_test_package_commands.py b/testing/mochitest/mach_test_package_commands.py
index 01e0167e1d..91a2a3182d 100644
--- a/testing/mochitest/mach_test_package_commands.py
+++ b/testing/mochitest/mach_test_package_commands.py
@@ -25,7 +25,7 @@ def run_mochitest(context, **kwargs):
     if args.test_paths:
         test_root = os.path.join(context.package_root, 'mochitest', 'tests')
         normalize = partial(context.normalize_test_path, test_root)
-        args.test_paths = map(normalize, args.test_paths)
+        args.test_paths = list(map(normalize, args.test_paths))
 
     import mozinfo
     return run_mochitest_desktop(context, args)
diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py
index 796a29b0dc..555cebdabe 100644
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -5,7 +5,7 @@
 from abc import ABCMeta, abstractmethod, abstractproperty
 from argparse import ArgumentParser, SUPPRESS
 from distutils.util import strtobool
-from urlparse import urlparse
+from urllib.parse import urlparse
 import json
 import os
 import tempfile
@@ -15,6 +15,7 @@ from mozprofile import DEFAULT_PORTS
 import mozinfo
 import mozlog
 import moznetwork
+import six
 
 
 here = os.path.abspath(os.path.dirname(__file__))
@@ -63,9 +64,7 @@ def get_default_valgrind_suppression_files():
     return rv
 
 
-class ArgumentContainer():
-    __metaclass__ = ABCMeta
-
+class ArgumentContainer(six.with_metaclass(ABCMeta)):
     @abstractproperty
     def args(self):
         pass
@@ -982,7 +981,7 @@ class MochitestArgumentParser(ArgumentParser):
 
         if self.app not in container_map:
             self.error("Unrecognized app '{}'! Must be one of: {}".format(
-                self.app, ', '.join(container_map.keys())))
+                self.app, ', '.join(list(container_map.keys()))))
 
         defaults = {}
         for container in self.containers:
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_base.py b/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_base.py
index 8235666bbb..21a1254ae6 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_base.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_base.py
@@ -118,7 +118,7 @@ class StreamBase(object):
                     'Receiving %d byte failed. Peer (%r) closed connection' %
                     (length, (self._request.connection.remote_addr,)))
             return read_bytes
-        except socket.error, e:
+        except socket.error as e:
             # Catch a socket.error. Because it's not a child class of the
             # IOError prior to Python 2.6, we cannot omit this except clause.
             # Use %s rather than %r for the exception to use human friendly
@@ -126,7 +126,7 @@ class StreamBase(object):
             raise ConnectionTerminatedException(
                 'Receiving %d byte failed. socket.error (%s) occurred' %
                 (length, e))
-        except IOError, e:
+        except IOError as e:
             # Also catch an IOError because mod_python throws it.
             raise ConnectionTerminatedException(
                 'Receiving %d byte failed. IOError (%s) occurred' %
@@ -139,7 +139,7 @@ class StreamBase(object):
 
         try:
             self._request.connection.write(bytes_to_write)
-        except Exception, e:
+        except Exception as e:
             util.prepend_message_to_exception(
                     'Failed to send message to %r: ' %
                             (self._request.connection.remote_addr,),
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_hybi.py b/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_hybi.py
index 104221b4c3..5ae839e70a 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_hybi.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/_stream_hybi.py
@@ -501,7 +501,7 @@ class Stream(StreamBase):
             raise BadOperationException(
                 'Requested send_message after sending out a closing handshake')
 
-        if binary and isinstance(message, unicode):
+        if binary and isinstance(message, str):
             raise BadOperationException(
                 'Message for binary frame must be instance of str')
 
@@ -538,7 +538,7 @@ class Stream(StreamBase):
                 # at least one frame is sent.
                 if len(message) <= bytes_written:
                     break
-        except ValueError, e:
+        except ValueError as e:
             raise BadOperationException(e)
 
     def _get_message_from_frame(self, frame):
@@ -677,7 +677,7 @@ class Stream(StreamBase):
             if handler:
                 handler(self._request, message)
                 return
-        except AttributeError, e:
+        except AttributeError as e:
             pass
         self._send_pong(message)
 
@@ -704,7 +704,7 @@ class Stream(StreamBase):
                     break
                 else:
                     inflight_pings.append(expected_body)
-            except IndexError, e:
+            except IndexError as e:
                 # The received pong was unsolicited pong. Keep the
                 # ping queue as is.
                 self._ping_queue = inflight_pings
@@ -715,7 +715,7 @@ class Stream(StreamBase):
             handler = self._request.on_pong_handler
             if handler:
                 handler(self._request, message)
-        except AttributeError, e:
+        except AttributeError as e:
             pass
 
     def receive_message(self):
@@ -780,7 +780,7 @@ class Stream(StreamBase):
                 # CHARACTER.
                 try:
                     return message.decode('utf-8')
-                except UnicodeDecodeError, e:
+                except UnicodeDecodeError as e:
                     raise InvalidUTF8Exception(e)
             elif self._original_opcode == common.OPCODE_BINARY:
                 return message
@@ -837,7 +837,7 @@ class Stream(StreamBase):
                     'close reason must not be specified if code is None')
             reason = ''
         else:
-            if not isinstance(reason, str) and not isinstance(reason, unicode):
+            if not isinstance(reason, str) and not isinstance(reason, str):
                 raise BadOperationException(
                     'close reason must be an instance of str or unicode')
 
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/common.py b/testing/mochitest/pywebsocket/mod_pywebsocket/common.py
index 8c15242841..f80734c48c 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/common.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/common.py
@@ -233,7 +233,7 @@ def _parse_extension(state):
 
         try:
             _parse_extension_param(state, extension)
-        except ExtensionParsingException, e:
+        except ExtensionParsingException as e:
             raise ExtensionParsingException(
                 'Failed to parse parameter for %r (%r)' %
                 (extension_token, e))
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/dispatch.py b/testing/mochitest/pywebsocket/mod_pywebsocket/dispatch.py
index 96c91e0c90..2591fe8b9e 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/dispatch.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/dispatch.py
@@ -143,7 +143,7 @@ def _source_handler_file(handler_definition):
 
     global_dic = {}
     try:
-        exec handler_definition in global_dic
+        exec(handler_definition, global_dic)
     except Exception:
         raise DispatchException('Error in sourcing handler:' +
                                 util.get_stack_trace())
@@ -254,12 +254,12 @@ class Dispatcher(object):
         do_extra_handshake_ = handler_suite.do_extra_handshake
         try:
             do_extra_handshake_(request)
-        except handshake.AbortedByUserException, e:
+        except handshake.AbortedByUserException as e:
             # Re-raise to tell the caller of this function to finish this
             # connection without sending any error.
             self._logger.debug('%s', util.get_stack_trace())
             raise
-        except Exception, e:
+        except Exception as e:
             util.prepend_message_to_exception(
                     '%s raised exception for %s: ' % (
                             _DO_EXTRA_HANDSHAKE_HANDLER_NAME,
@@ -296,28 +296,28 @@ class Dispatcher(object):
             if not request.server_terminated:
                 request.ws_stream.close_connection()
         # Catch non-critical exceptions the handler didn't handle.
-        except handshake.AbortedByUserException, e:
+        except handshake.AbortedByUserException as e:
             self._logger.debug('%s', util.get_stack_trace())
             raise
-        except msgutil.BadOperationException, e:
+        except msgutil.BadOperationException as e:
             self._logger.debug('%s', e)
             request.ws_stream.close_connection(
                 common.STATUS_INTERNAL_ENDPOINT_ERROR)
-        except msgutil.InvalidFrameException, e:
+        except msgutil.InvalidFrameException as e:
             # InvalidFrameException must be caught before
             # ConnectionTerminatedException that catches InvalidFrameException.
             self._logger.debug('%s', e)
             request.ws_stream.close_connection(common.STATUS_PROTOCOL_ERROR)
-        except msgutil.UnsupportedFrameException, e:
+        except msgutil.UnsupportedFrameException as e:
             self._logger.debug('%s', e)
             request.ws_stream.close_connection(common.STATUS_UNSUPPORTED_DATA)
-        except stream.InvalidUTF8Exception, e:
+        except stream.InvalidUTF8Exception as e:
             self._logger.debug('%s', e)
             request.ws_stream.close_connection(
                 common.STATUS_INVALID_FRAME_PAYLOAD_DATA)
-        except msgutil.ConnectionTerminatedException, e:
+        except msgutil.ConnectionTerminatedException as e:
             self._logger.debug('%s', e)
-        except Exception, e:
+        except Exception as e:
             # Any other exceptions are forwarded to the caller of this
             # function.
             util.prepend_message_to_exception(
@@ -379,7 +379,7 @@ class Dispatcher(object):
                 continue
             try:
                 handler_suite = _source_handler_file(open(path).read())
-            except DispatchException, e:
+            except DispatchException as e:
                 self._source_warnings.append('%s: %s' % (path, e))
                 continue
             resource = convert(path)
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/extensions.py b/testing/mochitest/pywebsocket/mod_pywebsocket/extensions.py
index 1edd988f61..6ab90ce1ae 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/extensions.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/extensions.py
@@ -185,7 +185,7 @@ class DeflateFrameExtensionProcessor(ExtensionProcessorInterface):
                 self._WINDOW_BITS_PARAM)
             try:
                 window_bits = _parse_window_bits(window_bits)
-            except ValueError, e:
+            except ValueError as e:
                 return None
 
         no_context_takeover = self._request.has_parameter(
@@ -381,7 +381,7 @@ class PerMessageDeflateExtensionProcessor(ExtensionProcessorInterface):
             try:
                 server_max_window_bits = _parse_window_bits(
                     server_max_window_bits)
-            except ValueError, e:
+            except ValueError as e:
                 self._logger.debug('Bad %s parameter: %r',
                                    self._SERVER_MAX_WINDOW_BITS_PARAM,
                                    e)
@@ -717,7 +717,7 @@ class MuxExtensionProcessor(ExtensionProcessorInterface):
         if quota is not None:
             try:
                 quota = int(quota)
-            except ValueError, e:
+            except ValueError as e:
                 return None
             if quota < 0 or quota >= 2 ** 32:
                 return None
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/__init__.py b/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/__init__.py
index 194f6b395a..707263a69f 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/__init__.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/__init__.py
@@ -90,15 +90,15 @@ def do_handshake(request, dispatcher, allowDraft75=False, strict=False):
             handshaker.do_handshake()
             _LOGGER.info('Established (%s protocol)', name)
             return
-        except HandshakeException, e:
+        except HandshakeException as e:
             _LOGGER.debug(
                 'Failed to complete opening handshake as %s protocol: %r',
                 name, e)
             if e.status:
                 raise e
-        except AbortedByUserException, e:
+        except AbortedByUserException as e:
             raise
-        except VersionException, e:
+        except VersionException as e:
             raise
 
     # TODO(toyoshim): Add a test to cover the case all handshakers fail.
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/_base.py b/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/_base.py
index c993a584b7..0af05242bf 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/_base.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/_base.py
@@ -111,7 +111,7 @@ def parse_host_header(request):
         return fields[0], get_default_port(request.is_https())
     try:
         return fields[0], int(fields[1])
-    except ValueError, e:
+    except ValueError as e:
         raise HandshakeException('Invalid port number format: %r' % e)
 
 
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/hybi.py b/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/hybi.py
index 44e71f179f..853c928bcb 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/hybi.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/handshake/hybi.py
@@ -112,7 +112,7 @@ class Handshaker(object):
 
         try:
             connection_tokens = parse_token_list(connection)
-        except HandshakeException, e:
+        except HandshakeException as e:
             raise HandshakeException(
                 'Failed to parse %s: %s' % (common.CONNECTION_HEADER, e))
 
@@ -182,8 +182,7 @@ class Handshaker(object):
 
             # Extra handshake handler may modify/remove processors.
             self._dispatcher.do_extra_handshake(self._request)
-            processors = filter(lambda processor: processor is not None,
-                                self._request.ws_extension_processors)
+            processors = [processor for processor in self._request.ws_extension_processors if processor is not None]
 
             # Ask each processor if there are extensions on the request which
             # cannot co-exist. When processor decided other processors cannot
@@ -194,8 +193,7 @@ class Handshaker(object):
                 if processor.is_active():
                     processor.check_consistency_with_other_processors(
                         processors)
-            processors = filter(lambda processor: processor.is_active(),
-                                processors)
+            processors = [processor for processor in processors if processor.is_active()]
 
             accepted_extensions = []
 
@@ -220,8 +218,7 @@ class Handshaker(object):
                 self._request.mux_processor = processors[mux_index]
                 self._request.mux_processor.set_extensions(
                     logical_channel_extensions)
-                processors = filter(lambda processor: processor.is_active(),
-                                    processors)
+                processors = [processor for processor in processors if processor.is_active()]
 
             stream_options = StreamOptions()
 
@@ -242,7 +239,7 @@ class Handshaker(object):
                     continue
 
                 # Inactivate all of the following compression extensions.
-                for j in xrange(index + 1, len(processors)):
+                for j in range(index + 1, len(processors)):
                     if is_compression_extension(processors[j].name()):
                         processors[j].set_active(False)
 
@@ -250,7 +247,7 @@ class Handshaker(object):
                 self._request.ws_extensions = accepted_extensions
                 self._logger.debug(
                     'Extensions accepted: %r',
-                    map(common.ExtensionParameter.name, accepted_extensions))
+                    list(map(common.ExtensionParameter.name, accepted_extensions)))
             else:
                 self._request.ws_extensions = None
 
@@ -273,7 +270,7 @@ class Handshaker(object):
                         'request any subprotocol')
 
             self._send_handshake(accept)
-        except HandshakeException, e:
+        except HandshakeException as e:
             if not e.status:
                 # Fallback to 400 bad request by default.
                 e.status = common.HTTP_STATUS_BAD_REQUEST
@@ -330,14 +327,14 @@ class Handshaker(object):
         try:
             self._request.ws_requested_extensions = common.parse_extensions(
                 extensions_header)
-        except common.ExtensionParsingException, e:
+        except common.ExtensionParsingException as e:
             raise HandshakeException(
                 'Failed to parse Sec-WebSocket-Extensions header: %r' % e)
 
         self._logger.debug(
             'Extensions requested: %r',
-            map(common.ExtensionParameter.name,
-                self._request.ws_requested_extensions))
+            list(map(common.ExtensionParameter.name,
+                self._request.ws_requested_extensions)))
 
     def _validate_key(self, key):
         if key.find(',') >= 0:
@@ -356,7 +353,7 @@ class Handshaker(object):
                 decoded_key = base64.b64decode(key)
                 if len(decoded_key) == 16:
                     key_is_valid = True
-        except TypeError, e:
+        except TypeError as e:
             pass
 
         if not key_is_valid:
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/headerparserhandler.py b/testing/mochitest/pywebsocket/mod_pywebsocket/headerparserhandler.py
index c244421cf7..bfee5c3359 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/headerparserhandler.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/headerparserhandler.py
@@ -199,7 +199,7 @@ def headerparserhandler(request):
             request.log_error(
                 'mod_pywebsocket: Fallback to Apache', apache.APLOG_INFO)
             return apache.DECLINED
-    except dispatch.DispatchException, e:
+    except dispatch.DispatchException as e:
         request.log_error(
             'mod_pywebsocket: Dispatch failed for error: %s' % e,
             apache.APLOG_INFO)
@@ -215,14 +215,14 @@ def headerparserhandler(request):
         try:
             handshake.do_handshake(
                 request, _dispatcher, allowDraft75=allow_draft75)
-        except handshake.VersionException, e:
+        except handshake.VersionException as e:
             request.log_error(
                 'mod_pywebsocket: Handshake failed for version error: %s' % e,
                 apache.APLOG_INFO)
             request.err_headers_out.add(common.SEC_WEBSOCKET_VERSION_HEADER,
                                         e.supported_versions)
             return apache.HTTP_BAD_REQUEST
-        except handshake.HandshakeException, e:
+        except handshake.HandshakeException as e:
             # Handshake for ws/wss failed.
             # Send http response with error status.
             request.log_error(
@@ -233,9 +233,9 @@ def headerparserhandler(request):
         handshake_is_done = True
         request._dispatcher = _dispatcher
         _dispatcher.transfer_data(request)
-    except handshake.AbortedByUserException, e:
+    except handshake.AbortedByUserException as e:
         request.log_error('mod_pywebsocket: Aborted: %s' % e, apache.APLOG_INFO)
-    except Exception, e:
+    except Exception as e:
         # DispatchException can also be thrown if something is wrong in
         # pywebsocket code. It's caught here, then.
 
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/http_header_util.py b/testing/mochitest/pywebsocket/mod_pywebsocket/http_header_util.py
index b774653932..0afa19c087 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/http_header_util.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/http_header_util.py
@@ -33,7 +33,7 @@ in HTTP RFC http://www.ietf.org/rfc/rfc2616.txt.
 """
 
 
-import urlparse
+import six.moves.urllib.parse
 
 
 _SEPARATORS = '()<>@,;:\\"/[]?={} \t'
@@ -218,7 +218,7 @@ def quote_if_necessary(s):
 def parse_uri(uri):
     """Parse absolute URI then return host, port and resource."""
 
-    parsed = urlparse.urlsplit(uri)
+    parsed = six.moves.urllib.parse.urlsplit(uri)
     if parsed.scheme != 'wss' and parsed.scheme != 'ws':
         # |uri| must be a relative URI.
         # TODO(toyoshim): Should validate |uri|.
@@ -230,7 +230,7 @@ def parse_uri(uri):
     port = None
     try:
         port = parsed.port
-    except ValueError, e:
+    except ValueError as e:
         # port property cause ValueError on invalid null port description like
         # 'ws://host:/path'.
         return None, None, None
@@ -253,11 +253,11 @@ def parse_uri(uri):
 
 
 try:
-    urlparse.uses_netloc.index('ws')
-except ValueError, e:
+    six.moves.urllib.parse.uses_netloc.index('ws')
+except ValueError as e:
     # urlparse in Python2.5.1 doesn't have 'ws' and 'wss' entries.
-    urlparse.uses_netloc.append('ws')
-    urlparse.uses_netloc.append('wss')
+    six.moves.urllib.parse.uses_netloc.append('ws')
+    six.moves.urllib.parse.uses_netloc.append('wss')
 
 
 # vi:sts=4 sw=4 et
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/memorizingfile.py b/testing/mochitest/pywebsocket/mod_pywebsocket/memorizingfile.py
index 4d4cd95859..e2b4a3eb75 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/memorizingfile.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/memorizingfile.py
@@ -47,14 +47,14 @@ class MemorizingFile(object):
     the control reaches WebSocketRequestHandler.
     """
 
-    def __init__(self, file_, max_memorized_lines=sys.maxint):
+    def __init__(self, file_, max_memorized_lines=sys.maxsize):
         """Construct an instance.
 
         Args:
             file_: the file object to wrap.
             max_memorized_lines: the maximum number of lines to memorize.
                 Only the first max_memorized_lines are memorized.
-                Default: sys.maxint.
+                Default: sys.maxsize.
         """
 
         self._file = file_
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/msgutil.py b/testing/mochitest/pywebsocket/mod_pywebsocket/msgutil.py
index 4c1a0114b4..22a7013cd0 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/msgutil.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/msgutil.py
@@ -38,7 +38,7 @@ bytes writing/reading.
 """
 
 
-import Queue
+import six.moves.queue
 import threading
 
 
@@ -124,7 +124,7 @@ class MessageReceiver(threading.Thread):
 
         threading.Thread.__init__(self)
         self._request = request
-        self._queue = Queue.Queue()
+        self._queue = six.moves.queue.Queue()
         self._onmessage = onmessage
         self._stop_requested = False
         self.setDaemon(True)
@@ -157,7 +157,7 @@ class MessageReceiver(threading.Thread):
         """
         try:
             message = self._queue.get_nowait()
-        except Queue.Empty:
+        except six.moves.queue.Empty:
             message = None
         return message
 
@@ -190,7 +190,7 @@ class MessageSender(threading.Thread):
         """
         threading.Thread.__init__(self)
         self._request = request
-        self._queue = Queue.Queue()
+        self._queue = six.moves.queue.Queue()
         self.setDaemon(True)
         self.start()
 
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/mux.py b/testing/mochitest/pywebsocket/mod_pywebsocket/mux.py
index 76334685b3..bc508e7dc6 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/mux.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/mux.py
@@ -353,7 +353,7 @@ class _MuxFramePayloadParser(object):
 
         try:
             size = self._read_number()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_INVALID_MUX_CONTROL_BLOCK,
                                           str(e))
         pos = self._read_position
@@ -376,7 +376,7 @@ class _MuxFramePayloadParser(object):
         encoding = first_byte & 0x3
         try:
             control_block.channel_id = self.read_channel_id()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_INVALID_MUX_CONTROL_BLOCK)
         control_block.encoding = encoding
         encoded_handshake = self._read_size_and_contents()
@@ -394,7 +394,7 @@ class _MuxFramePayloadParser(object):
         control_block.encoding = first_byte & 0x3
         try:
             control_block.channel_id = self.read_channel_id()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_INVALID_MUX_CONTROL_BLOCK)
         control_block.encoded_handshake = self._read_size_and_contents()
         return control_block
@@ -409,7 +409,7 @@ class _MuxFramePayloadParser(object):
         try:
             control_block.channel_id = self.read_channel_id()
             control_block.send_quota = self._read_number()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_INVALID_MUX_CONTROL_BLOCK,
                                           str(e))
 
@@ -424,7 +424,7 @@ class _MuxFramePayloadParser(object):
 
         try:
             control_block.channel_id = self.read_channel_id()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_INVALID_MUX_CONTROL_BLOCK)
         reason = self._read_size_and_contents()
         if len(reason) == 0:
@@ -449,7 +449,7 @@ class _MuxFramePayloadParser(object):
         try:
             control_block.slots = self._read_number()
             control_block.send_quota = self._read_number()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_INVALID_MUX_CONTROL_BLOCK,
                                           str(e))
         return control_block
@@ -921,7 +921,7 @@ class _LogicalStream(Stream):
 
                 opcode = common.OPCODE_CONTINUATION
 
-        except ValueError, e:
+        except ValueError as e:
             raise BadOperationException(e)
         finally:
             self._write_inner_frame_semaphore.release()
@@ -960,7 +960,7 @@ class _LogicalStream(Stream):
             raise BadOperationException(
                 'Requested send_message after sending out a closing handshake')
 
-        if binary and isinstance(message, unicode):
+        if binary and isinstance(message, str):
             raise BadOperationException(
                 'Message for binary frame must be instance of str')
 
@@ -1029,7 +1029,7 @@ class _LogicalStream(Stream):
         # connection has closed gracefully.
         try:
             return Stream.receive_message(self)
-        except LogicalConnectionClosedException, e:
+        except LogicalConnectionClosedException as e:
             self._logger.debug('%s', e)
             return None
 
@@ -1144,7 +1144,7 @@ class _PhysicalConnectionWriter(threading.Thread):
         try:
             self._mux_handler.physical_stream.send_message(
                 message=message, end=True, binary=True)
-        except Exception, e:
+        except Exception as e:
             util.prepend_message_to_exception(
                 'Failed to send message to %r: ' %
                 (self._mux_handler.physical_connection.remote_addr,), e)
@@ -1185,7 +1185,7 @@ class _PhysicalConnectionWriter(threading.Thread):
                 # by the reader thread.
                 self._mux_handler.physical_stream.close_connection(
                     self._close_code, wait_response=False)
-            except Exception, e:
+            except Exception as e:
                 util.prepend_message_to_exception(
                     'Failed to close the physical connection: %r' % e)
                 raise
@@ -1233,20 +1233,20 @@ class _PhysicalConnectionReader(threading.Thread):
                         'Received a text message on physical connection')
                     break
 
-            except ConnectionTerminatedException, e:
+            except ConnectionTerminatedException as e:
                 self._logger.debug('%s', e)
                 break
 
             try:
                 self._mux_handler.dispatch_message(message)
-            except PhysicalConnectionError, e:
+            except PhysicalConnectionError as e:
                 self._mux_handler.fail_physical_connection(
                     e.drop_code, e.message)
                 break
-            except LogicalChannelError, e:
+            except LogicalChannelError as e:
                 self._mux_handler.fail_logical_channel(
                     e.channel_id, e.drop_code, e.message)
-            except Exception, e:
+            except Exception as e:
                 self._logger.debug(traceback.format_exc())
                 break
 
@@ -1278,7 +1278,7 @@ class _Worker(threading.Thread):
         try:
             # Non-critical exceptions will be handled by dispatcher.
             self._mux_handler.dispatcher.transfer_data(self._request)
-        except LogicalChannelError, e:
+        except LogicalChannelError as e:
             self._mux_handler.fail_logical_channel(
                 e.channel_id, e.drop_code, e.message)
         finally:
@@ -1392,7 +1392,7 @@ class _HandshakeDeltaBase(object):
             for key, value in delta.items():
                 # The spec requires that a header with an empty value is
                 # removed from the delta base.
-                if len(value) == 0 and headers.has_key(key):
+                if len(value) == 0 and key in headers:
                     del headers[key]
                 else:
                     headers[key] = value
@@ -1621,19 +1621,19 @@ class _MuxHandler(object):
                                     send_quota, receive_quota)
         try:
             handshaker.do_handshake()
-        except handshake.VersionException, e:
+        except handshake.VersionException as e:
             self._logger.info('%s', e)
             self._send_error_add_channel_response(
                 request.channel_id, status=common.HTTP_STATUS_BAD_REQUEST)
             return False
-        except handshake.HandshakeException, e:
+        except handshake.HandshakeException as e:
             # TODO(bashi): Should we _Fail the Logical Channel_ with 3001
             # instead?
             self._logger.info('%s', e)
             self._send_error_add_channel_response(request.channel_id,
                                                   status=e.status)
             return False
-        except handshake.AbortedByUserException, e:
+        except handshake.AbortedByUserException as e:
             self._logger.info('%s', e)
             self._send_error_add_channel_response(request.channel_id)
             return False
@@ -1660,7 +1660,7 @@ class _MuxHandler(object):
     def _process_add_channel_request(self, block):
         try:
             logical_request = self._create_logical_request(block)
-        except ValueError, e:
+        except ValueError as e:
             self._logger.debug('Failed to create logical request: %r' % e)
             self._send_error_add_channel_response(
                 block.channel_id, status=common.HTTP_STATUS_BAD_REQUEST)
@@ -1767,7 +1767,7 @@ class _MuxHandler(object):
         parser = _MuxFramePayloadParser(message)
         try:
             channel_id = parser.read_channel_id()
-        except ValueError, e:
+        except ValueError as e:
             raise PhysicalConnectionError(_DROP_CODE_CHANNEL_ID_TRUNCATED)
         if channel_id == _CONTROL_CHANNEL_ID:
             self._process_control_blocks(parser)
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/util.py b/testing/mochitest/pywebsocket/mod_pywebsocket/util.py
index d224ae3942..726c7339b7 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/util.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/util.py
@@ -147,7 +147,7 @@ def wrap_popen3_for_win(cygwin_path):
 
 
 def hexify(s):
-    return ' '.join(map(lambda x: '%02x' % ord(x), s))
+    return ' '.join(['%02x' % ord(x) for x in s])
 
 
 def get_class_logger(o):
@@ -191,11 +191,11 @@ class RepeatedXorMasker(object):
 
         # Use temporary local variables to eliminate the cost to access
         # attributes
-        masking_key = map(ord, self._masking_key)
+        masking_key = list(map(ord, self._masking_key))
         masking_key_size = len(masking_key)
         masking_key_index = self._masking_key_index
 
-        for i in xrange(len(result)):
+        for i in range(len(result)):
             result[i] ^= masking_key[masking_key_index]
             masking_key_index = (masking_key_index + 1) % masking_key_size
 
diff --git a/testing/mochitest/pywebsocket/mod_pywebsocket/xhr_benchmark_handler.py b/testing/mochitest/pywebsocket/mod_pywebsocket/xhr_benchmark_handler.py
index 6735c7e2a3..dd227a410b 100644
--- a/testing/mochitest/pywebsocket/mod_pywebsocket/xhr_benchmark_handler.py
+++ b/testing/mochitest/pywebsocket/mod_pywebsocket/xhr_benchmark_handler.py
@@ -60,7 +60,7 @@ class XHRBenchmarkHandler(object):
         bytes_to_send = request_array[0]
         try:
             bytes_to_send = int(bytes_to_send)
-        except ValueError, e:
+        except ValueError as e:
             self._logger.debug('Malformed size parameter: %r', bytes_to_send)
             return
         self._logger.debug('Requested to send %s bytes', bytes_to_send)
diff --git a/testing/mochitest/pywebsocket/standalone.py b/testing/mochitest/pywebsocket/standalone.py
index e176327439..56cc8c1265 100755
--- a/testing/mochitest/pywebsocket/standalone.py
+++ b/testing/mochitest/pywebsocket/standalone.py
@@ -155,13 +155,13 @@ It may execute arbitrary Python code or external programs. It should not be
 used outside a firewall.
 """
 
-import BaseHTTPServer
-import CGIHTTPServer
-import SimpleHTTPServer
-import SocketServer
-import ConfigParser
+import six.moves.BaseHTTPServer
+import six.moves.CGIHTTPServer
+import six.moves.SimpleHTTPServer
+import six.moves.socketserver
+import six.moves.configparser
 import base64
-import httplib
+import six.moves.http_client
 import logging
 import logging.handlers
 import optparse
@@ -347,7 +347,8 @@ class _StandaloneSSLConnection(object):
 
         try:
             return self._connection.recv(bufsize)
-        except OpenSSL.SSL.SysCallError, (err, message):
+        except OpenSSL.SSL.SysCallError as xxx_todo_changeme:
+            (err, message) = xxx_todo_changeme.args
             if err == -1:
                 # Suppress "unexpected EOF" exception. See the OpenSSL document
                 # for SSL_get_error.
@@ -375,13 +376,13 @@ def _alias_handlers(dispatcher, websock_handlers_map_file):
             try:
                 dispatcher.add_resource_path_alias(
                     m.group(1), m.group(2))
-            except dispatch.DispatchException, e:
+            except dispatch.DispatchException as e:
                 logging.error(str(e))
     finally:
         fp.close()
 
 
-class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
+class WebSocketServer(six.moves.socketserver.ThreadingMixIn, six.moves.BaseHTTPServer.HTTPServer):
     """HTTPServer specialized for WebSocket."""
 
     # Overrides SocketServer.ThreadingMixIn.daemon_threads
@@ -415,7 +416,7 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
         self.__ws_is_shut_down = threading.Event()
         self.__ws_serving = False
 
-        SocketServer.BaseServer.__init__(
+        six.moves.socketserver.BaseServer.__init__(
             self, (options.server_host, options.port), WebSocketRequestHandler)
 
         # Expose the options object to allow handler objects access it. We name
@@ -451,7 +452,7 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
             family, socktype, proto, canonname, sockaddr = addrinfo
             try:
                 socket_ = socket.socket(family, socktype)
-            except Exception, e:
+            except Exception as e:
                 self._logger.info('Skip by failure: %r', e)
                 continue
             server_options = self.websocket_server_options
@@ -489,7 +490,7 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
                 socket_.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
             try:
                 socket_.bind(self.server_address)
-            except Exception, e:
+            except Exception as e:
                 self._logger.info('Skip by failure: %r', e)
                 socket_.close()
                 failed_sockets.append(socketinfo)
@@ -518,7 +519,7 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
             self._logger.info('Listen on: %r', addrinfo)
             try:
                 socket_.listen(self.request_queue_size)
-            except Exception, e:
+            except Exception as e:
                 self._logger.info('Skip by failure: %r', e)
                 socket_.close()
                 failed_sockets.append(socketinfo)
@@ -569,7 +570,7 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
             if server_options.tls_module == _TLS_BY_STANDARD_MODULE:
                 try:
                     accepted_socket.do_handshake()
-                except ssl.SSLError, e:
+                except ssl.SSLError as e:
                     self._logger.debug('%r', e)
                     raise
 
@@ -608,7 +609,7 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
                 # TODO(tyoshino): Convert all kinds of errors.
                 try:
                     accepted_socket.do_handshake()
-                except OpenSSL.SSL.Error, e:
+                except OpenSSL.SSL.Error as e:
                     # Set errno part to 1 (SSL_ERROR_SSL) like the ssl module
                     # does.
                     self._logger.debug('%r', e)
@@ -652,11 +653,11 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
         self.__ws_is_shut_down.wait()
 
 
-class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
+class WebSocketRequestHandler(six.moves.CGIHTTPServer.CGIHTTPRequestHandler):
     """CGIHTTPRequestHandler specialized for WebSocket."""
 
     # Use httplib.HTTPMessage instead of mimetools.Message.
-    MessageClass = httplib.HTTPMessage
+    MessageClass = six.moves.http_client.HTTPMessage
 
     def setup(self):
         """Override SocketServer.StreamRequestHandler.setup to wrap rfile
@@ -672,7 +673,7 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
         # Call superclass's setup to prepare rfile, wfile, etc. See setup
         # definition on the root class SocketServer.StreamRequestHandler to
         # understand what this does.
-        CGIHTTPServer.CGIHTTPRequestHandler.setup(self)
+        six.moves.CGIHTTPServer.CGIHTTPRequestHandler.setup(self)
 
         self.rfile = memorizingfile.MemorizingFile(
             self.rfile,
@@ -690,7 +691,7 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
             self.is_executable = self._options.is_executable_method
 
         # This actually calls BaseRequestHandler.__init__.
-        CGIHTTPServer.CGIHTTPRequestHandler.__init__(
+        six.moves.CGIHTTPServer.CGIHTTPRequestHandler.__init__(
             self, request, client_address, server)
 
     def parse_request(self):
@@ -711,7 +712,7 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
         # handling (self.path, self.command, self.requestline, etc. See also
         # how _StandaloneRequest's members are implemented using these
         # attributes).
-        if not CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self):
+        if not six.moves.CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self):
             return False
 
         if self._options.use_basic_auth:
@@ -772,7 +773,7 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
                                   self.path)
                 self._logger.info('Fallback to CGIHTTPRequestHandler')
                 return True
-        except dispatch.DispatchException, e:
+        except dispatch.DispatchException as e:
             self._logger.info('Dispatch failed for error: %s', e)
             self.send_error(e.status)
             return False
@@ -788,14 +789,14 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
                     self._options.dispatcher,
                     allowDraft75=self._options.allow_draft75,
                     strict=self._options.strict)
-            except handshake.VersionException, e:
+            except handshake.VersionException as e:
                 self._logger.info('Handshake failed for version error: %s', e)
                 self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                 self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                  e.supported_versions)
                 self.end_headers()
                 return False
-            except handshake.HandshakeException, e:
+            except handshake.HandshakeException as e:
                 # Handshake for ws(s) failed.
                 self._logger.info('Handshake failed for error: %s', e)
                 self.send_error(e.status)
@@ -803,7 +804,7 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
 
             request._dispatcher = self._options.dispatcher
             self._options.dispatcher.transfer_data(request)
-        except handshake.AbortedByUserException, e:
+        except handshake.AbortedByUserException as e:
             self._logger.info('Aborted: %s', e)
         return False
 
@@ -831,7 +832,7 @@ class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
         rather than a CGI script.
         """
 
-        if CGIHTTPServer.CGIHTTPRequestHandler.is_cgi(self):
+        if six.moves.CGIHTTPServer.CGIHTTPRequestHandler.is_cgi(self):
             if '..' in self.path:
                 return False
             # strip query parameter from request path
@@ -1044,14 +1045,14 @@ def _parse_args_and_config(args):
     if temporary_options.config_file:
         try:
             config_fp = open(temporary_options.config_file, 'r')
-        except IOError, e:
+        except IOError as e:
             logging.critical(
                 'Failed to open configuration file %r: %r',
                 temporary_options.config_file,
                 e)
             sys.exit(1)
 
-        config_parser = ConfigParser.SafeConfigParser()
+        config_parser = six.moves.configparser.SafeConfigParser()
         config_parser.readfp(config_fp)
         config_fp.close()
 
@@ -1172,7 +1173,7 @@ def _main(args=None):
 
         server = WebSocketServer(options)
         server.serve_forever()
-    except Exception, e:
+    except Exception as e:
         logging.critical('mod_pywebsocket: %s' % e)
         logging.critical('mod_pywebsocket: %s' % util.get_stack_trace())
         sys.exit(1)
diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py
index 07547dd238..79c1cd53cf 100644
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -7,8 +7,10 @@ Runs the Mochitest test harness.
 """
 
 from __future__ import with_statement
+from __future__ import print_function
 import os
 import sys
+import six
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
 sys.path.insert(0, SCRIPT_DIR)
 
@@ -32,7 +34,7 @@ import sys
 import tempfile
 import time
 import traceback
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import uuid
 import zipfile
 import bisection
@@ -51,7 +53,7 @@ from manifestparser.filters import (
 try:
     from marionette_driver.addons import Addons
     from marionette_harness import Marionette
-except ImportError, e:
+except ImportError as e:
     # Defer ImportError until attempt to use Marionette
     def reraise(*args, **kwargs):
         raise(e)
@@ -63,7 +65,7 @@ from mochitest_options import (
 )
 from mozprofile import Profile, Preferences
 from mozprofile.permissions import ServerLocations
-from urllib import quote_plus as encodeURIComponent
+from urllib.parse import quote_plus as encodeURIComponent
 from mozlog.formatters import TbplFormatter
 from mozlog import commandline
 from mozrunner.utils import get_stack_fixer_function, test_environment
@@ -179,8 +181,8 @@ class MessageLogger(object):
         if 'message' in message:
             if isinstance(message['message'], bytes):
                 message['message'] = message['message'].decode('utf-8', 'replace')
-            elif not isinstance(message['message'], unicode):
-                message['message'] = unicode(message['message'])
+            elif not isinstance(message['message'], str):
+                message['message'] = str(message['message'])
 
     def parse_line(self, line):
         """Takes a given line of input (structured or not) and
@@ -472,7 +474,7 @@ class MochitestServer(object):
 
     def stop(self):
         try:
-            with urllib2.urlopen(self.shutdownURL) as c:
+            with six.moves.urllib.request.urlopen(self.shutdownURL) as c:
                 c.read()
 
             # TODO: need ProcessHandler.poll()
@@ -717,7 +719,7 @@ def findTestMediaDevices(log):
     def sine_source_loaded():
         o = subprocess.check_output(
             ['/usr/bin/pactl', 'list', 'short', 'modules'])
-        return filter(lambda x: 'module-sine-source' in x, o.splitlines())
+        return [x for x in o.splitlines() if 'module-sine-source' in x]
 
     if not sine_source_loaded():
         # Load module-sine-source
@@ -850,7 +852,7 @@ class MochitestDesktop(object):
         try:
             return dict(parseKeyValue(extraPrefs, context='--setpref='))
         except KeyValueParseError as e:
-            print str(e)
+            print(str(e))
             sys.exit(1)
 
     def getFullPath(self, path):
@@ -1448,7 +1450,7 @@ toolbar#nav-bar {
 
         # strip certain unnecessary items to avoid serialization errors in json.dumps()
         d = dict((k, v) for k, v in options.__dict__.items() if (v is None) or
-                 isinstance(v, (basestring, numbers.Number)))
+                 isinstance(v, (str, numbers.Number)))
         d['testRoot'] = self.testRoot
         if options.jscov_dir_prefix:
             d['jscovDirPrefix'] = options.jscov_dir_prefix
@@ -2213,7 +2215,7 @@ toolbar#nav-bar {
 
         result = 1  # default value, if no tests are run.
         for d in dirs:
-            print "dir: %s" % d
+            print("dir: %s" % d)
 
             # BEGIN LEAKCHECK HACK
             # Leak checking was broken in mochitest unnoticed for a length of time. During
@@ -2255,20 +2257,20 @@ toolbar#nav-bar {
 
         # printing total number of tests
         if options.flavor == 'browser':
-            print "TEST-INFO | checking window state"
-            print "Browser Chrome Test Summary"
-            print "\tPassed: %s" % self.countpass
-            print "\tFailed: %s" % self.countfail
-            print "\tTodo: %s" % self.counttodo
-            print "\tMode: %s" % e10s_mode
-            print "*** End BrowserChrome Test Results ***"
+            print("TEST-INFO | checking window state")
+            print("Browser Chrome Test Summary")
+            print("\tPassed: %s" % self.countpass)
+            print("\tFailed: %s" % self.countfail)
+            print("\tTodo: %s" % self.counttodo)
+            print("\tMode: %s" % e10s_mode)
+            print("*** End BrowserChrome Test Results ***")
         else:
-            print "0 INFO TEST-START | Shutdown"
-            print "1 INFO Passed:  %s" % self.countpass
-            print "2 INFO Failed:  %s" % self.countfail
-            print "3 INFO Todo:    %s" % self.counttodo
-            print "4 INFO Mode:    %s" % e10s_mode
-            print "5 INFO SimpleTest FINISHED"
+            print("0 INFO TEST-START | Shutdown")
+            print("1 INFO Passed:  %s" % self.countpass)
+            print("2 INFO Failed:  %s" % self.countfail)
+            print("3 INFO Todo:    %s" % self.counttodo)
+            print("4 INFO Mode:    %s" % e10s_mode)
+            print("5 INFO SimpleTest FINISHED")
 
         return result
 
@@ -2687,7 +2689,7 @@ def run_test_harness(parser, options):
     parser.validate(options)
 
     logger_options = {
-        key: value for key, value in vars(options).iteritems()
+        key: value for key, value in vars(options.items())
         if key.startswith('log') or key == 'valgrind'}
 
     runner = MochitestDesktop(logger_options, quiet=options.quiet)
diff --git a/testing/mozbase/docs/_static/structured_example.py b/testing/mozbase/docs/_static/structured_example.py
index 2bbc038103..3a888fe338 100644
--- a/testing/mozbase/docs/_static/structured_example.py
+++ b/testing/mozbase/docs/_static/structured_example.py
@@ -12,7 +12,7 @@ class TestAssertion(Exception):
 
 def assert_equals(a, b):
     if a != b:
-        raise TestAssertion("%r not equal to %r" % (a, b))
+        raise TestAssertion("{!r} not equal to {!r}".format(a, b))
 
 
 def expected(status):
@@ -42,13 +42,13 @@ def test_expected_fail():
     assert_equals(2 + 2, 5)
 
 
-class TestRunner(object):
+class TestRunner:
 
     def __init__(self):
         self.logger = get_default_logger(component='TestRunner')
 
     def gather_tests(self):
-        for item in globals().itervalues():
+        for item in globals(.values()):
             if isinstance(item, types.FunctionType) and item.__name__.startswith("test_"):
                 yield item.__name__, item
 
diff --git a/testing/mozbase/docs/conf.py b/testing/mozbase/docs/conf.py
index 95d6de64ba..e2cf079996 100644
--- a/testing/mozbase/docs/conf.py
+++ b/testing/mozbase/docs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 # MozBase documentation build configuration file, created by
 # sphinx-quickstart on Mon Oct 22 14:02:17 2012.
@@ -47,8 +46,8 @@ source_suffix = '.rst'
 master_doc = 'index'
 
 # General information about the project.
-project = u'MozBase'
-copyright = u'2012, Mozilla Automation and Tools team'
+project = 'MozBase'
+copyright = '2012, Mozilla Automation and Tools team'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -199,8 +198,8 @@ latex_elements = {
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-    ('index', 'MozBase.tex', u'MozBase Documentation',
-     u'Mozilla Automation and Tools team', 'manual'),
+    ('index', 'MozBase.tex', 'MozBase Documentation',
+     'Mozilla Automation and Tools team', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -229,8 +228,8 @@ latex_documents = [
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('index', 'mozbase', u'MozBase Documentation',
-     [u'Mozilla Automation and Tools team'], 1)
+    ('index', 'mozbase', 'MozBase Documentation',
+     ['Mozilla Automation and Tools team'], 1)
 ]
 
 # If true, show URL addresses after external links.
@@ -243,8 +242,8 @@ man_pages = [
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    ('index', 'MozBase', u'MozBase Documentation',
-     u'Mozilla Automation and Tools team', 'MozBase', 'One line description of project.',
+    ('index', 'MozBase', 'MozBase Documentation',
+     'Mozilla Automation and Tools team', 'MozBase', 'One line description of project.',
      'Miscellaneous'),
 ]
 
diff --git a/testing/mozbase/manifestparser/manifestparser/cli.py b/testing/mozbase/manifestparser/manifestparser/cli.py
index 482575d292..d5d18580eb 100644
--- a/testing/mozbase/manifestparser/manifestparser/cli.py
+++ b/testing/mozbase/manifestparser/manifestparser/cli.py
@@ -7,6 +7,7 @@
 Mozilla universal manifest parser
 """
 
+from __future__ import print_function
 from optparse import OptionParser
 import os
 import sys
@@ -81,7 +82,7 @@ class Copy(CLICommand):
         # parse the arguments
         try:
             kwargs, tags, args = parse_args(args)
-        except ParserError, e:
+        except ParserError as e:
             self._parser.error(e.message)
 
         # make sure we have some manifests, otherwise it will
@@ -132,7 +133,7 @@ class CreateCLI(CLICommand):
             manifest = convert(args, pattern=options.pattern, ignore=options.ignore,
                                write=options.in_place)
         if manifest:
-            print manifest
+            print(manifest)
 
 
 class WriteCLI(CLICommand):
@@ -146,7 +147,7 @@ class WriteCLI(CLICommand):
         # parse the arguments
         try:
             kwargs, tags, args = parse_args(args)
-        except ParserError, e:
+        except ParserError as e:
             self._parser.error(e.message)
 
         # make sure we have some manifests, otherwise it will
@@ -175,9 +176,9 @@ class HelpCLI(CLICommand):
             commands[args[0]](self._parser).parser().print_help()
         else:
             self._parser.print_help()
-            print '\nCommands:'
+            print('\nCommands:')
             for command in sorted(commands):
-                print '  %s : %s' % (command, commands[command].__doc__.strip())
+                print(('  %s : %s' % (command, commands[command].__doc__.strip())))
 
 
 class UpdateCLI(CLICommand):
@@ -190,7 +191,7 @@ class UpdateCLI(CLICommand):
         # parse the arguments
         try:
             kwargs, tags, args = parse_args(args)
-        except ParserError, e:
+        except ParserError as e:
             self._parser.error(e.message)
 
         # make sure we have some manifests, otherwise it will
diff --git a/testing/mozbase/manifestparser/manifestparser/expression.py b/testing/mozbase/manifestparser/manifestparser/expression.py
index 6b705ead9c..6484e23c8a 100644
--- a/testing/mozbase/manifestparser/manifestparser/expression.py
+++ b/testing/mozbase/manifestparser/manifestparser/expression.py
@@ -195,7 +195,7 @@ class ExpressionParser(object):
         LITERAL ::= BOOL | INT | IDENT | STRING
         BOOL ::= 'true' | 'false'
         INT ::= [0-9]+
-        IDENT ::= [a-zA-Z_]\w*
+        IDENT ::= [a-zA-Z_]\\w*
         STRING ::= '"' [^\"] '"' | ''' [^\'] '''
 
     At its core, expressions consist of booleans, integers, identifiers and.
@@ -275,7 +275,7 @@ class ExpressionParser(object):
         """
         if not isinstance(self.token, expected):
             raise Exception("Unexpected token!")
-        self.token = self.iter.next()
+        self.token = next(self.iter)
 
     def expression(self, rbp=0):
         """
@@ -283,11 +283,11 @@ class ExpressionParser(object):
         right binding power greater than rbp is encountered.
         """
         t = self.token
-        self.token = self.iter.next()
+        self.token = next(self.iter)
         left = t.nud(self)
         while rbp < self.token.lbp:
             t = self.token
-            self.token = self.iter.next()
+            self.token = next(self.iter)
             left = t.led(self, left)
         return left
 
@@ -299,7 +299,7 @@ class ExpressionParser(object):
         """
         try:
             self.iter = self._tokenize()
-            self.token = self.iter.next()
+            self.token = next(self.iter)
             return self.expression()
         except:
             extype, ex, tb = sys.exc_info()
@@ -307,7 +307,7 @@ class ExpressionParser(object):
             raise ParseError("could not parse: "
                              "%s\nexception: %svariables: %s" % (self.text,
                                                                  formatted,
-                                                                 self.valuemapping)), None, tb
+                                                                 self.valuemapping)).with_traceback(tb)
 
     __call__ = parse
 
diff --git a/testing/mozbase/manifestparser/manifestparser/filters.py b/testing/mozbase/manifestparser/manifestparser/filters.py
index e832c0da65..0742b96eaf 100644
--- a/testing/mozbase/manifestparser/manifestparser/filters.py
+++ b/testing/mozbase/manifestparser/manifestparser/filters.py
@@ -8,7 +8,8 @@ dictionary of values, and returns a new iterable of test objects. It is
 possible to define custom filters if the built-in ones are not enough.
 """
 
-from collections import defaultdict, MutableSequence
+from collections import defaultdict
+from collections.abc import MutableSequence
 import itertools
 import os
 
@@ -79,7 +80,7 @@ def exists(tests, values):
 
 # built-in instance filters
 
-class InstanceFilter(object):
+class InstanceFilter:
     """
     Generally only one instance of a class filter should be applied at a time.
     Two instances of `InstanceFilter` are considered equal if they have the
@@ -92,7 +93,7 @@ class InstanceFilter(object):
     def __init__(self, *args, **kwargs):
         self.fmt_args = ', '.join(itertools.chain(
             [str(a) for a in args],
-            ['{}={}'.format(k, v) for k, v in kwargs.iteritems()]))
+            ['{}={}'.format(k, v) for k, v in kwargs.items()]))
 
     def __eq__(self, other):
         if self.unique:
@@ -249,10 +250,9 @@ class chunk_by_dir(InstanceFilter):
         # be yielded for reporting purposes. Put them all in chunk 1 for
         # simplicity.
         if self.this_chunk == 1:
-            disabled_dirs = [v for k, v in tests_by_dir.iteritems()
+            disabled_dirs = [v for k, v in tests_by_dir.items()
                              if k not in ordered_dirs]
-            for disabled_test in itertools.chain(*disabled_dirs):
-                yield disabled_test
+            yield from itertools.chain(*disabled_dirs)
 
 
 class chunk_by_runtime(InstanceFilter):
@@ -283,7 +283,7 @@ class chunk_by_runtime(InstanceFilter):
 
     def __call__(self, tests, values):
         tests = list(tests)
-        manifests = set(t['manifest'] for t in tests)
+        manifests = {t['manifest'] for t in tests}
 
         def total_runtime(tests):
             return sum(self.runtimes[t['relpath']] for t in tests
@@ -326,7 +326,7 @@ class tags(InstanceFilter):
 
     def __init__(self, tags):
         InstanceFilter.__init__(self, tags)
-        if isinstance(tags, basestring):
+        if isinstance(tags, str):
             tags = [tags]
         self.tags = tags
 
@@ -349,7 +349,7 @@ class pathprefix(InstanceFilter):
 
     def __init__(self, paths):
         InstanceFilter.__init__(self, paths)
-        if isinstance(paths, basestring):
+        if isinstance(paths, str):
             paths = [paths]
         self.paths = paths
 
diff --git a/testing/mozbase/manifestparser/manifestparser/ini.py b/testing/mozbase/manifestparser/manifestparser/ini.py
index 5117dd1ae8..254146f90e 100644
--- a/testing/mozbase/manifestparser/manifestparser/ini.py
+++ b/testing/mozbase/manifestparser/manifestparser/ini.py
@@ -27,11 +27,14 @@ def read_ini(fp, variables=None, default='DEFAULT', defaults_only=False,
     sections = []
     key = value = None
     section_names = set()
-    if isinstance(fp, basestring):
-        fp = file(fp)
+    if isinstance(fp, (str, bytes)):
+        fp = open(fp if isinstance(fp, str) else fp.decode('utf-8'))
 
     # read the lines
-    for (linenum, line) in enumerate(fp.read().splitlines(), start=1):
+    content = fp.read()
+    if isinstance(content, bytes):
+        content = content.decode('utf-8')
+    for (linenum, line) in enumerate(content.splitlines(), start=1):
 
         stripped = line.strip()
 
@@ -60,7 +63,7 @@ def read_ini(fp, variables=None, default='DEFAULT', defaults_only=False,
 
             if strict:
                 # make sure this section doesn't already exist
-                assert section not in section_names, "Section '%s' already found in '%s'" % (
+                assert section not in section_names, "Section '{}' already found in '{}'".format(
                     section, section_names)
 
             section_names.add(section)
@@ -90,7 +93,7 @@ def read_ini(fp, variables=None, default='DEFAULT', defaults_only=False,
         else:
             # continuation line ?
             if line[0].isspace() and key:
-                value = '%s%s%s' % (value, os.linesep, stripped)
+                value = '{}{}{}'.format(value, os.linesep, stripped)
                 current_section[key] = value
             else:
                 # something bad happened!
diff --git a/testing/mozbase/manifestparser/manifestparser/manifestparser.py b/testing/mozbase/manifestparser/manifestparser/manifestparser.py
index 23f14d3f87..216f79b8dc 100644
--- a/testing/mozbase/manifestparser/manifestparser/manifestparser.py
+++ b/testing/mozbase/manifestparser/manifestparser/manifestparser.py
@@ -2,7 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from StringIO import StringIO
+from io import StringIO
 import json
 import fnmatch
 import os
@@ -21,7 +21,7 @@ from .filters import (
 __all__ = ['ManifestParser', 'TestManifest', 'convert']
 
 relpath = os.path.relpath
-string = (basestring,)
+string = (str,)
 
 
 # path normalization
@@ -42,7 +42,7 @@ def denormalize_path(path):
 
 # objects for parsing manifests
 
-class ManifestParser(object):
+class ManifestParser:
     """read .ini manifests"""
 
     def __init__(self, manifests=(), defaults=None, strict=True, rootdir=None,
@@ -110,7 +110,7 @@ class ManifestParser(object):
             if not self.path_exists(include_file):
                 message = "Included file '%s' does not exist" % include_file
                 if self.strict:
-                    raise IOError(message)
+                    raise OSError(message)
                 else:
                     sys.stderr.write("%s\n" % message)
                     return
@@ -178,7 +178,7 @@ class ManifestParser(object):
 
             # otherwise an item
             # apply ancestor defaults, while maintaining current file priority
-            data = dict(self._ancestor_defaults.items() + data.items())
+            data = dict(list(self._ancestor_defaults.items()) + list(data.items()))
 
             test = data
             test['name'] = section
@@ -249,7 +249,7 @@ class ManifestParser(object):
         missing = [filename for filename in filenames
                    if isinstance(filename, string) and not self.path_exists(filename)]
         if missing:
-            raise IOError('Missing files: %s' % ', '.join(missing))
+            raise OSError('Missing files: %s' % ', '.join(missing))
 
         # default variables
         _defaults = defaults.copy() or self._defaults.copy()
@@ -370,11 +370,11 @@ class ManifestParser(object):
         if missing:
             missing_paths = [test['path'] for test in missing]
             if self.strict:
-                raise IOError("Strict mode enabled, test paths must exist. "
+                raise OSError("Strict mode enabled, test paths must exist. "
                               "The following test(s) are missing: %s" %
                               json.dumps(missing_paths, indent=2))
-            print >> sys.stderr, "Warning: The following test(s) are missing: %s" % \
-                json.dumps(missing_paths, indent=2)
+            print("Warning: The following test(s) are missing: %s" %
+                json.dumps(missing_paths, indent=2), file=sys.stderr)
         return missing
 
     def verifyDirectory(self, directories, pattern=None, extensions=None):
@@ -384,8 +384,8 @@ class ManifestParser(object):
         (missing_from_filesystem, missing_from_manifest)
         """
 
-        files = set([])
-        if isinstance(directories, basestring):
+        files = set()
+        if isinstance(directories, str):
             directories = [directories]
 
         # get files in directories
@@ -437,7 +437,7 @@ class ManifestParser(object):
         local_kwargs = local_kwargs or {}
 
         # create the query
-        tags = set([])
+        tags = set()
         tags.update(global_tags)
         tags.update(local_tags)
         kwargs = {}
@@ -449,12 +449,12 @@ class ManifestParser(object):
 
         # print the .ini manifest
         if global_tags or global_kwargs:
-            print >> fp, '[DEFAULT]'
+            print('[DEFAULT]', file=fp)
             for tag in global_tags:
-                print >> fp, '%s =' % tag
+                print('%s =' % tag, file=fp)
             for key, value in global_kwargs.items():
-                print >> fp, '%s = %s' % (key, value)
-            print >> fp
+                print('{} = {}'.format(key, value, file=fp))
+            print(self.rootdir, file=fp)
 
         for test in tests:
             test = test.copy()  # don't overwrite
@@ -463,9 +463,9 @@ class ManifestParser(object):
             if not os.path.isabs(path):
                 path = test['path']
                 if self.rootdir:
-                    path = relpath(test['path'], self.rootdir)
+                    path = relpath(test['path'])
                 path = denormalize_path(path)
-            print >> fp, '[%s]' % path
+            print('[%s]' % path, file=fp)
 
             # reserved keywords:
             reserved = ['path', 'name', 'here', 'manifest', 'relpath', 'ancestor-manifest']
@@ -476,8 +476,8 @@ class ManifestParser(object):
                     continue
                 if key in global_tags and not test[key]:
                     continue
-                print >> fp, '%s = %s' % (key, test[key])
-            print >> fp
+                print('{} = {}'.format(key, test[key], file=fp))
+            print(directory, rootdir=None, *tags, **kwargs, file=fp)
 
         if close:
             # close the created file
@@ -489,7 +489,7 @@ class ManifestParser(object):
         value = fp.getvalue()
         return value
 
-    def copy(self, directory, rootdir=None, *tags, **kwargs):
+    def copy(self):
         """
         copy the manifests and associated tests
         - directory : directory to copy to
@@ -564,8 +564,8 @@ class ManifestParser(object):
                 if not os.path.exists(source):
                     message = "Missing test: '%s' does not exist!"
                     if self.strict:
-                        raise IOError(message)
-                    print >> sys.stderr, message + " Skipping."
+                        raise OSError(message)
+                    print(message + " Skipping.", file=sys.stderr)
                     continue
                 destination = os.path.join(rootdir, _relpath)
                 shutil.copy(source, destination)
@@ -578,7 +578,7 @@ class ManifestParser(object):
         internal function to import directories
         """
 
-        if isinstance(pattern, basestring):
+        if isinstance(pattern, str):
             patterns = [pattern]
         else:
             patterns = pattern
@@ -654,7 +654,7 @@ class ManifestParser(object):
         manifest_dict = {}
 
         if os.path.basename(filename) != filename:
-            raise IOError("filename should not include directory name")
+            raise OSError("filename should not include directory name")
 
         # no need to hit directories more than once
         _directories = directories
@@ -670,9 +670,9 @@ class ManifestParser(object):
             if (dirnames or filenames) and not (os.path.exists(manifest_path) and overwrite):
                 with file(manifest_path, 'w') as manifest:
                     for dirname in dirnames:
-                        print >> manifest, '[include:%s]' % os.path.join(dirname, filename)
+                        print('[include:%s]' % os.path.join(dirname, filename, file=manifest))
                     for _filename in filenames:
-                        print >> manifest, '[%s]' % _filename
+                        print('[%s]' % _filename, file=manifest)
 
                 # add to list of manifests
                 manifest_dict.setdefault(directory, manifest_path)
@@ -722,8 +722,8 @@ class ManifestParser(object):
                              for filename in filenames]
 
             # write to manifest
-            print >> write, '\n'.join(['[%s]' % denormalize_path(filename)
-                                       for filename in filenames])
+            print('\n'.join(['[%s]' % denormalize_path(filename)
+                                       for filename in filenames]), file=write)
 
         cls._walk_directories(directories, callback, pattern=pattern, ignore=ignore)
 
diff --git a/testing/mozbase/manifestparser/tests/test_chunking.py b/testing/mozbase/manifestparser/tests/test_chunking.py
index 719bbca80c..56022dd7de 100644
--- a/testing/mozbase/manifestparser/tests/test_chunking.py
+++ b/testing/mozbase/manifestparser/tests/test_chunking.py
@@ -63,7 +63,7 @@ class ChunkBySlice(TestCase):
         self.run_all_combos(num_tests=10, disabled=[1, 2])
 
         num_tests = 67
-        disabled = list(i for i in xrange(num_tests) if i % 4 == 0)
+        disabled = list(i for i in range(num_tests) if i % 4 == 0)
         self.run_all_combos(num_tests=num_tests, disabled=disabled)
 
     def test_two_times_more_chunks_than_tests(self):
@@ -85,7 +85,7 @@ class ChunkByDir(TestCase):
                         { :  }
         """
         i = 0
-        for d, num in dirs.iteritems():
+        for d, num in dirs.items():
             for j in range(num):
                 i += 1
                 name = 'test%i' % i
@@ -113,7 +113,7 @@ class ChunkByDir(TestCase):
                     f = chunk_by_dir(this, total, depth)
                     res.append(list(f(tests, {})))
 
-                lengths = map(num_groups, res)
+                lengths = list(map(num_groups, res))
                 # the chunk with the most dirs should have at most one more
                 # dir than the chunk with the least dirs
                 self.assertLessEqual(max(lengths) - min(lengths), 1)
@@ -176,7 +176,7 @@ class ChunkByRuntime(TestCase):
                      { :  }
         """
         i = 0
-        for d, num in dirs.iteritems():
+        for d, num in dirs.items():
             for j in range(num):
                 i += 1
                 name = 'test%i' % i
@@ -192,7 +192,7 @@ class ChunkByRuntime(TestCase):
         return runtimes
 
     def chunk_by_round_robin(self, tests, runtimes):
-        manifests = set(t['manifest'] for t in tests)
+        manifests = {t['manifest'] for t in tests}
         tests_by_manifest = []
         for manifest in manifests:
             mtests = [t for t in tests if t['manifest'] == manifest]
diff --git a/testing/mozbase/manifestparser/tests/test_convert_directory.py b/testing/mozbase/manifestparser/tests/test_convert_directory.py
index 12776e4e4f..669ca84ada 100755
--- a/testing/mozbase/manifestparser/tests/test_convert_directory.py
+++ b/testing/mozbase/manifestparser/tests/test_convert_directory.py
@@ -39,10 +39,10 @@ class TestDirectoryConversion(unittest.TestCase):
         if directory is None:
             directory = create_realpath_tempdir()
         for i in files:
-            file(os.path.join(directory, i), 'w').write(i)
+            open(os.path.join(directory, i), 'w').write(i)
         subdir = os.path.join(directory, 'subdir')
         os.mkdir(subdir)
-        file(os.path.join(subdir, 'subfile'), 'w').write('baz')
+        open(os.path.join(subdir, 'subfile'), 'w').write('baz')
         return directory
 
     def test_directory_to_manifest(self):
@@ -141,13 +141,13 @@ class TestDirectoryConversion(unittest.TestCase):
         # boilerplate
         tempdir = create_realpath_tempdir()
         for i in range(10):
-            file(os.path.join(tempdir, str(i)), 'w').write(str(i))
+            open(os.path.join(tempdir, str(i)), 'w').write(str(i))
 
         # otherwise empty directory with a manifest file
         newtempdir = create_realpath_tempdir()
         manifest_file = os.path.join(newtempdir, 'manifest.ini')
         manifest_contents = str(convert([tempdir], relative_to=tempdir))
-        with file(manifest_file, 'w') as f:
+        with open(manifest_file, 'w') as f:
             f.write(manifest_contents)
 
         # get the manifest
@@ -165,11 +165,11 @@ class TestDirectoryConversion(unittest.TestCase):
                          ['1', 'manifest.ini'])
 
         # Update that one file and copy all the "tests":
-        file(os.path.join(tempdir, '1'), 'w').write('secret door')
+        open(os.path.join(tempdir, '1'), 'w').write('secret door')
         manifest.update(tempdir)
         self.assertEqual(sorted(os.listdir(newtempdir)),
                          ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'manifest.ini'])
-        self.assertEqual(file(os.path.join(newtempdir, '1')).read().strip(),
+        self.assertEqual(open(os.path.join(newtempdir, '1')).read().strip(),
                          'secret door')
 
         # clean up:
diff --git a/testing/mozbase/manifestparser/tests/test_convert_symlinks.py b/testing/mozbase/manifestparser/tests/test_convert_symlinks.py
index 9a0640b4bd..dac027cdff 100755
--- a/testing/mozbase/manifestparser/tests/test_convert_symlinks.py
+++ b/testing/mozbase/manifestparser/tests/test_convert_symlinks.py
@@ -24,10 +24,10 @@ class TestSymlinkConversion(unittest.TestCase):
         if directory is None:
             directory = tempfile.mkdtemp()
         for i in files:
-            file(os.path.join(directory, i), 'w').write(i)
+            open(os.path.join(directory, i), 'w').write(i)
         subdir = os.path.join(directory, 'subdir')
         os.mkdir(subdir)
-        file(os.path.join(subdir, 'subfile'), 'w').write('baz')
+        open(os.path.join(subdir, 'subfile'), 'w').write('baz')
         return directory
 
     def test_relpath(self):
diff --git a/testing/mozbase/manifestparser/tests/test_filters.py b/testing/mozbase/manifestparser/tests/test_filters.py
index 5b0772492e..5334ae2b55 100644
--- a/testing/mozbase/manifestparser/tests/test_filters.py
+++ b/testing/mozbase/manifestparser/tests/test_filters.py
@@ -28,19 +28,19 @@ class FilterList(unittest.TestCase):
         fl = filterlist()
 
         fl.extend([foo, bar])
-        self.assertEquals(len(fl), 2)
+        self.assertEqual(len(fl), 2)
         self.assertTrue(foo in fl)
 
         fl.append(baz)
-        self.assertEquals(fl[2], baz)
+        self.assertEqual(fl[2], baz)
 
         fl.remove(baz)
         self.assertFalse(baz in fl)
 
         item = fl.pop()
-        self.assertEquals(item, bar)
+        self.assertEqual(item, bar)
 
-        self.assertEquals(fl.index(foo), 0)
+        self.assertEqual(fl.index(foo), 0)
 
         del fl[0]
         self.assertFalse(foo in fl)
@@ -57,8 +57,8 @@ class FilterList(unittest.TestCase):
         bar = lambda x, y: x
         sub = subsuite('foo')
         fl = filterlist([foo, bar, sub])
-        self.assertEquals(len(fl), 3)
-        self.assertEquals(fl[0], foo)
+        self.assertEqual(len(fl), 3)
+        self.assertEqual(fl[0], foo)
 
         with self.assertRaises(ValueError):
             fl.append(foo)
@@ -75,7 +75,7 @@ class FilterList(unittest.TestCase):
             fl.append(tag1)
 
         fl.append(tag2)
-        self.assertEquals(len(fl), 2)
+        self.assertEqual(len(fl), 2)
 
     def test_filters_run_in_order(self):
         a = lambda x, y: x
@@ -89,7 +89,7 @@ class FilterList(unittest.TestCase):
         fl.append(c)
         fl.extend([d, e])
         fl += [f]
-        self.assertEquals([i for i in fl], [a, b, c, d, e, f])
+        self.assertEqual([i for i in fl], [a, b, c, d, e, f])
 
 
 class BuiltinFilters(unittest.TestCase):
@@ -109,7 +109,7 @@ class BuiltinFilters(unittest.TestCase):
     def test_skip_if(self):
         tests = deepcopy(self.tests)
         tests = list(skip_if(tests, {}))
-        self.assertEquals(len(tests), len(self.tests))
+        self.assertEqual(len(tests), len(self.tests))
 
         tests = deepcopy(self.tests)
         tests = list(skip_if(tests, {'foo': 'bar'}))
@@ -122,7 +122,7 @@ class BuiltinFilters(unittest.TestCase):
 
         tests = deepcopy(self.tests)
         tests = list(run_if(tests, {'foo': 'bar'}))
-        self.assertEquals(len(tests), len(self.tests))
+        self.assertEqual(len(tests), len(self.tests))
 
     def test_fail_if(self):
         tests = deepcopy(self.tests)
@@ -131,7 +131,7 @@ class BuiltinFilters(unittest.TestCase):
 
         tests = deepcopy(self.tests)
         tests = list(fail_if(tests, {'foo': 'bar'}))
-        self.assertEquals(tests[3]['expected'], 'fail')
+        self.assertEqual(tests[3]['expected'], 'fail')
 
     def test_enabled(self):
         tests = deepcopy(self.tests)
@@ -145,11 +145,11 @@ class BuiltinFilters(unittest.TestCase):
         tests = deepcopy(self.tests)
         tests = list(sub1(tests, {}))
         self.assertNotIn(self.tests[5], tests)
-        self.assertEquals(len(tests), len(self.tests) - 1)
+        self.assertEqual(len(tests), len(self.tests) - 1)
 
         tests = deepcopy(self.tests)
         tests = list(sub2(tests, {}))
-        self.assertEquals(len(tests), 1)
+        self.assertEqual(len(tests), 1)
         self.assertIn(self.tests[5], tests)
 
     def test_subsuite_condition(self):
@@ -164,9 +164,9 @@ class BuiltinFilters(unittest.TestCase):
 
         tests = deepcopy(self.tests)
         tests = list(sub2(tests, {'foo': 'bar'}))
-        self.assertEquals(len(tests), 2)
-        self.assertEquals(tests[0]['name'], 'test5')
-        self.assertEquals(tests[1]['name'], 'test6')
+        self.assertEqual(len(tests), 2)
+        self.assertEqual(tests[0]['name'], 'test5')
+        self.assertEqual(tests[1]['name'], 'test6')
 
     def test_tags(self):
         ftags1 = tags([])
@@ -174,9 +174,9 @@ class BuiltinFilters(unittest.TestCase):
 
         tests = deepcopy(self.tests)
         tests = list(ftags1(tests, {}))
-        self.assertEquals(len(tests), 0)
+        self.assertEqual(len(tests), 0)
 
         tests = deepcopy(self.tests)
         tests = list(ftags2(tests, {}))
-        self.assertEquals(len(tests), 1)
+        self.assertEqual(len(tests), 1)
         self.assertIn(self.tests[7], tests)
diff --git a/testing/mozbase/manifestparser/tests/test_manifestparser.py b/testing/mozbase/manifestparser/tests/test_manifestparser.py
index ca80911fb9..0d3eaaf31d 100755
--- a/testing/mozbase/manifestparser/tests/test_manifestparser.py
+++ b/testing/mozbase/manifestparser/tests/test_manifestparser.py
@@ -29,11 +29,11 @@ class TestManifestParser(unittest.TestCase):
         mozmill_example = os.path.join(here, 'mozmill-example.ini')
         parser.read(mozmill_example)
         tests = parser.tests
-        self.assertEqual(len(tests), len(file(mozmill_example).read().strip().splitlines()))
+        self.assertEqual(len(tests), len(open(mozmill_example).read().strip().splitlines()))
 
         # Ensure that capitalization and order aren't an issue:
         lines = ['[%s]' % test['name'] for test in tests]
-        self.assertEqual(lines, file(mozmill_example).read().strip().splitlines())
+        self.assertEqual(lines, open(mozmill_example).read().strip().splitlines())
 
         # Show how you select subsets of tests:
         mozmill_restart_example = os.path.join(here, 'mozmill-restart-example.ini')
@@ -290,14 +290,14 @@ yellow = submarine"""  # noqa
         manifest_path = os.path.join(directory, 'verifyDirectory_incomplete.ini')
         manifest = ManifestParser(manifests=(manifest_path,))
         missing = manifest.verifyDirectory(directory, extensions=('.js',))
-        self.assertEqual(missing, (set(), set([test_1])))
+        self.assertEqual(missing, (set(), {test_1}))
 
         # filesystem is missing test_notappearinginthisfilm.js
         missing_test = os.path.join(directory, 'test_notappearinginthisfilm.js')
         manifest_path = os.path.join(directory, 'verifyDirectory_toocomplete.ini')
         manifest = ManifestParser(manifests=(manifest_path,))
         missing = manifest.verifyDirectory(directory, extensions=('.js',))
-        self.assertEqual(missing, (set([missing_test]), set()))
+        self.assertEqual(missing, ({missing_test}, set()))
 
     def test_just_defaults(self):
         """Ensure a manifest with just a DEFAULT section exposes that data."""
@@ -307,7 +307,7 @@ yellow = submarine"""  # noqa
         parser.read(manifest)
         self.assertEqual(len(parser.tests), 0)
         self.assertTrue(manifest in parser.manifest_defaults)
-        self.assertEquals(parser.manifest_defaults[manifest]['foo'], 'bar')
+        self.assertEqual(parser.manifest_defaults[manifest]['foo'], 'bar')
 
     def test_manifest_list(self):
         """
diff --git a/testing/mozbase/manifestparser/tests/test_read_ini.py b/testing/mozbase/manifestparser/tests/test_read_ini.py
index df4a8973b0..960c001535 100755
--- a/testing/mozbase/manifestparser/tests/test_read_ini.py
+++ b/testing/mozbase/manifestparser/tests/test_read_ini.py
@@ -12,7 +12,7 @@ http://docs.python.org/2/library/configparser.html
 
 import unittest
 from manifestparser import read_ini
-from ConfigParser import ConfigParser
+from configparser import ConfigParser
 from StringIO import StringIO
 
 
diff --git a/testing/mozbase/manifestparser/tests/test_testmanifest.py b/testing/mozbase/manifestparser/tests/test_testmanifest.py
index 5f79dd48a6..8ded6b2fc1 100644
--- a/testing/mozbase/manifestparser/tests/test_testmanifest.py
+++ b/testing/mozbase/manifestparser/tests/test_testmanifest.py
@@ -71,24 +71,24 @@ class TestTestManifest(unittest.TestCase):
 
         # 6 tests total
         tests = manifest.active_tests(exists=False, **info)
-        self.assertEquals(len(tests), 6)
+        self.assertEqual(len(tests), 6)
 
         # only 3 tests for subsuite bar when foo==bar
         tests = manifest.active_tests(exists=False,
                                       filters=[subsuite('bar')],
                                       **info)
-        self.assertEquals(len(tests), 3)
+        self.assertEqual(len(tests), 3)
 
         # only 1 test for subsuite baz, regardless of conditions
         other = {'something': 'else'}
         tests = manifest.active_tests(exists=False,
                                       filters=[subsuite('baz')],
                                       **info)
-        self.assertEquals(len(tests), 1)
+        self.assertEqual(len(tests), 1)
         tests = manifest.active_tests(exists=False,
                                       filters=[subsuite('baz')],
                                       **other)
-        self.assertEquals(len(tests), 1)
+        self.assertEqual(len(tests), 1)
 
         # 4 tests match when the condition doesn't match (all tests except
         # the unconditional subsuite)
@@ -96,7 +96,7 @@ class TestTestManifest(unittest.TestCase):
         tests = manifest.active_tests(exists=False,
                                       filters=[subsuite()],
                                       **info)
-        self.assertEquals(len(tests), 5)
+        self.assertEqual(len(tests), 5)
 
         # test for illegal subsuite value
         manifest.tests[0]['subsuite'] = 'subsuite=bar,foo=="bar",type="nothing"'
diff --git a/testing/mozbase/mozcrash/mozcrash/__init__.py b/testing/mozbase/mozcrash/mozcrash/__init__.py
index ec95442cf2..29a487571b 100644
--- a/testing/mozbase/mozcrash/mozcrash/__init__.py
+++ b/testing/mozbase/mozcrash/mozcrash/__init__.py
@@ -7,4 +7,4 @@ mozcrash is a library for getting a stack trace out of processes that have crash
 and left behind a minidump file using the Google Breakpad library.
 """
 
-from mozcrash import *
+from .mozcrash import *
diff --git a/testing/mozbase/mozcrash/mozcrash/mozcrash.py b/testing/mozbase/mozcrash/mozcrash/mozcrash.py
index c39e68f3a6..1da425b9d8 100644
--- a/testing/mozbase/mozcrash/mozcrash/mozcrash.py
+++ b/testing/mozbase/mozcrash/mozcrash/mozcrash.py
@@ -105,10 +105,10 @@ def check_for_crashes(dump_directory,
                 stackwalk_output.append("minidump_stackwalk exited with return code %d" %
                                         info.stackwalk_retcode)
             signature = info.signature if info.signature else "unknown top frame"
-            print "PROCESS-CRASH | %s | application crashed [%s]" % (test_name,
+            print("PROCESS-CRASH | %s | application crashed [%s]" % (test_name,)
                                                                      signature)
-            print '\n'.join(stackwalk_output)
-            print '\n'.join(info.stackwalk_errors)
+            print('\n'.join(stackwalk_output))
+            print('\n'.join(info.stackwalk_errors))
 
     return crash_count
 
@@ -371,11 +371,11 @@ def check_for_java_exception(logcat, test_name=None, quiet=False):
                 if m and m.group(1):
                     exception_location = m.group(1)
                 if not quiet:
-                    print "PROCESS-CRASH | %s | java-exception %s %s" % (test_name,
+                    print("PROCESS-CRASH | %s | java-exception %s %s" % (test_name,)
                                                                          exception_type,
                                                                          exception_location)
             else:
-                print "Automation Error: java exception in logcat at line " \
+                print("Automation Error: java exception in logcat at line " \)
                     "%d of %d: %s" % (i, len(logcat), line)
             break
 
diff --git a/testing/mozbase/mozcrash/tests/test.py b/testing/mozbase/mozcrash/tests/test.py
index 8f6b14f50b..1d71684dbb 100644
--- a/testing/mozbase/mozcrash/tests/test.py
+++ b/testing/mozbase/mozcrash/tests/test.py
@@ -9,7 +9,7 @@ import unittest
 import subprocess
 import tempfile
 import shutil
-import urlparse
+import six.moves.urllib.parse
 import zipfile
 import StringIO
 import mozcrash
@@ -25,17 +25,17 @@ def popen_factory(stdouts):
     Generate a class that can mock subprocess.Popen. |stdouts| is an iterable that
     should return an iterable for the stdout of each process in turn.
     """
-    class mock_popen(object):
+    class mock_popen:
 
         def __init__(self, args, *args_rest, **kwargs):
-            self.stdout = stdouts.next()
+            self.stdout = next(stdouts)
             self.returncode = 0
 
         def wait(self):
             return 0
 
         def communicate(self):
-            return (self.stdout.next(), "")
+            return (next(self.stdout), "")
 
     return mock_popen
 
@@ -77,7 +77,7 @@ class TestCrash(unittest.TestCase):
         """
         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
         self.stdouts.append(["this is some output"])
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 stackwalk_binary=self.stackwalk,
                                                 quiet=True))
@@ -89,7 +89,7 @@ class TestCrash(unittest.TestCase):
         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
         self.stdouts.append(["this is some output"])
         os.environ['MINIDUMP_STACKWALK'] = self.stackwalk
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 quiet=True))
         del os.environ['MINIDUMP_STACKWALK']
@@ -103,13 +103,13 @@ class TestCrash(unittest.TestCase):
         save_path = os.path.join(self.tempdir, "saved")
         os.mkdir(save_path)
         self.stdouts.append(["this is some output"])
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 stackwalk_binary=self.stackwalk,
                                                 dump_save_path=save_path,
                                                 quiet=True))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.dmp")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.extra")))
 
     def test_save_path_not_present(self):
         """
@@ -119,13 +119,13 @@ class TestCrash(unittest.TestCase):
         open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
         save_path = os.path.join(self.tempdir, "saved")
         self.stdouts.append(["this is some output"])
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 stackwalk_binary=self.stackwalk,
                                                 dump_save_path=save_path,
                                                 quiet=True))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.dmp")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.extra")))
 
     def test_save_path_isfile(self):
         """
@@ -137,13 +137,13 @@ class TestCrash(unittest.TestCase):
         save_path = os.path.join(self.tempdir, "saved")
         open(save_path, "w").write("junk")
         self.stdouts.append(["this is some output"])
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 stackwalk_binary=self.stackwalk,
                                                 dump_save_path=save_path,
                                                 quiet=True))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.dmp")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.extra")))
 
     def test_save_path_envvar(self):
         """
@@ -155,18 +155,18 @@ class TestCrash(unittest.TestCase):
         os.mkdir(save_path)
         self.stdouts.append(["this is some output"])
         os.environ['MINIDUMP_SAVE_PATH'] = save_path
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 stackwalk_binary=self.stackwalk,
                                                 quiet=True))
         del os.environ['MINIDUMP_SAVE_PATH']
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
-        self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.dmp")))
+        self.assertTrue(os.path.isfile(os.path.join(save_path, "test.extra")))
 
     def test_symbol_path_not_present(self):
         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
         self.stdouts.append(["this is some output"])
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path=None,
                                                 stackwalk_binary=self.stackwalk,
                                                 quiet=True))
@@ -193,9 +193,9 @@ class TestCrash(unittest.TestCase):
                                                 'path': '/symbols',
                                                 'function': get_symbols}])
         httpd.start()
-        symbol_url = urlparse.urlunsplit(('http', '%s:%d' % httpd.httpd.server_address,
+        symbol_url = six.moves.urllib.parse.urlunsplit(('http', '%s:%d' % httpd.httpd.server_address,
                                           '/symbols', '', ''))
-        self.assert_(mozcrash.check_for_crashes(self.tempdir,
+        self.assertTrue(mozcrash.check_for_crashes(self.tempdir,
                                                 symbol_url,
                                                 stackwalk_binary=self.stackwalk,
                                                 quiet=True))
@@ -217,7 +217,7 @@ class TestJavaException(unittest.TestCase):
         """
         Test for an exception which should be caught
         """
-        self.assert_(mozcrash.check_for_java_exception(self.test_log, quiet=True))
+        self.assertTrue(mozcrash.check_for_java_exception(self.test_log, quiet=True))
 
     def test_truncated_exception(self):
         """
@@ -226,7 +226,7 @@ class TestJavaException(unittest.TestCase):
         """
         truncated_log = list(self.test_log)
         truncated_log[0], truncated_log[1] = truncated_log[1], truncated_log[0]
-        self.assert_(mozcrash.check_for_java_exception(truncated_log, quiet=True))
+        self.assertTrue(mozcrash.check_for_java_exception(truncated_log, quiet=True))
 
     def test_unchecked_exception(self):
         """
@@ -235,7 +235,7 @@ class TestJavaException(unittest.TestCase):
         passable_log = list(self.test_log)
         passable_log[0] = "01-30 20:15:41.937 E/GeckoAppShell( 1703):" \
                           " >>> NOT-SO-BAD EXCEPTION FROM THREAD 9 (\"GeckoBackgroundThread\")"
-        self.assert_(not mozcrash.check_for_java_exception(passable_log, quiet=True))
+        self.assertTrue(not mozcrash.check_for_java_exception(passable_log, quiet=True))
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/testing/mozbase/mozdebug/mozdebug/__init__.py b/testing/mozbase/mozdebug/mozdebug/__init__.py
index 3450d755c7..63e9bd6140 100644
--- a/testing/mozbase/mozdebug/mozdebug/__init__.py
+++ b/testing/mozbase/mozdebug/mozdebug/__init__.py
@@ -28,4 +28,4 @@ debugger-specific arguments:
 
 """
 
-from mozdebug import *
+from .mozdebug import *
diff --git a/testing/mozbase/mozdebug/mozdebug/mozdebug.py b/testing/mozbase/mozdebug/mozdebug/mozdebug.py
index 6dd9e9fddd..8c6e9fbcc0 100755
--- a/testing/mozbase/mozdebug/mozdebug/mozdebug.py
+++ b/testing/mozbase/mozdebug/mozdebug/mozdebug.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import mozinfo
 from collections import namedtuple
@@ -163,7 +164,7 @@ def get_debugger_info(debugger, debuggerArgs=None, debuggerInteractive=False):
                 debuggerPath = debugger
 
     if not debuggerPath:
-        print 'Error: Could not find debugger %s.' % debugger
+        print(('Error: Could not find debugger %s.' % debugger))
         return None
 
     debuggerName = os.path.basename(debuggerPath).lower()
diff --git a/testing/mozbase/mozdevice/adb_tests/test_device_running_adb_as_root.py b/testing/mozbase/mozdevice/adb_tests/test_device_running_adb_as_root.py
index 2b223bb044..f871a0c3ed 100644
--- a/testing/mozbase/mozdevice/adb_tests/test_device_running_adb_as_root.py
+++ b/testing/mozbase/mozdevice/adb_tests/test_device_running_adb_as_root.py
@@ -5,6 +5,7 @@
  Running this test case requires various reboots which makes it a
  very slow test case to run.
 """
+from __future__ import print_function
 import unittest
 import sys
 
@@ -36,13 +37,13 @@ class TestFileOperations(unittest.TestCase):
 if __name__ == "__main__":
     dm = DeviceManagerADB()
     if not dm.devices():
-        print "There are no connected adb devices"
+        print("There are no connected adb devices")
         sys.exit(1)
     else:
         if not (int(dm._runCmd(["shell", "getprop", "ro.secure"]).output[0]) and
                 int(dm._runCmd(["shell", "getprop", "ro.debuggable"]).output[0])):
-            print "This test case is meant for devices with devices that start " \
-                "adbd as non-root and allows for adbd to be restarted as root."
+            print("This test case is meant for devices with devices that start " \
+                "adbd as non-root and allows for adbd to be restarted as root.")
             sys.exit(1)
 
     unittest.main()
diff --git a/testing/mozbase/mozdevice/adb_tests/test_devicemanagerADB.py b/testing/mozbase/mozdevice/adb_tests/test_devicemanagerADB.py
index 495e449a4a..c85ccee7f9 100644
--- a/testing/mozbase/mozdevice/adb_tests/test_devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/adb_tests/test_devicemanagerADB.py
@@ -34,6 +34,7 @@
  - uninstallAppAndReboot()
 """
 
+from __future__ import print_function
 import os
 import re
 import socket
@@ -207,13 +208,13 @@ class TestOther(DeviceManagerADBTestCase):
 if __name__ == '__main__':
     dm = DeviceManagerADB()
     if not dm.devices():
-        print "There are no connected adb devices"
+        print("There are no connected adb devices")
         sys.exit(1)
 
     if find_mount_permissions(dm, "/system") == "rw":
-        print "We've found out that /system is mounted as 'rw'. This is because the command " \
+        print("We've found out that /system is mounted as 'rw'. This is because the command " \
             "'adb remount' has been run before running this test case. Please reboot the device " \
-            "and try again."
+            "and try again.")
         sys.exit(1)
 
     unittest.main()
diff --git a/testing/mozbase/mozdevice/mozdevice/Zeroconf.py b/testing/mozbase/mozdevice/mozdevice/Zeroconf.py
index 54a5d53598..a709f5b290 100755
--- a/testing/mozbase/mozdevice/mozdevice/Zeroconf.py
+++ b/testing/mozbase/mozdevice/mozdevice/Zeroconf.py
@@ -74,6 +74,8 @@
                  ensure names end in '.local.'
                  timeout on receiving socket for clean shutdown"""
 
+from __future__ import print_function
+from functools import reduce
 __author__ = "Paul Scott-Murphy"
 __email__ = "paul at scott dash murphy dot com"
 __version__ = "0.12"
@@ -819,7 +821,7 @@ class DNSCache(object):
         """Returns a list of all entries"""
         def add(x, y): return x+y
         try:
-            return reduce(add, self.cache.values())
+            return reduce(add, list(self.cache.values()))
         except:
             return []
 
@@ -870,7 +872,7 @@ class Engine(threading.Thread):
     def getReaders(self):
         result = []
         self.condition.acquire()
-        result = self.readers.keys()
+        result = list(self.readers.keys())
         self.condition.release()
         return result
     
@@ -1062,7 +1064,7 @@ class ServiceInfo(object):
             for key in properties:
                 value = properties[key]
                 if value is None:
-                    suffix = ''.encode('utf-8')
+                    suffix = b''
                 elif isinstance(value, str):
                     suffix = value.encode('utf-8')
                 elif isinstance(value, int):
@@ -1071,7 +1073,7 @@ class ServiceInfo(object):
                     else:
                         suffix = 'false'
                 else:
-                    suffix = ''.encode('utf-8')
+                    suffix = b''
                 list.append('='.join((key, suffix)))
             for item in list:
                 result = ''.join((result, struct.pack('!c', chr(len(item))), item))
@@ -1540,21 +1542,21 @@ class Zeroconf(object):
 # query (for Zoe), and service unregistration.
 
 if __name__ == '__main__':    
-    print "Multicast DNS Service Discovery for Python, version", __version__
+    print(("Multicast DNS Service Discovery for Python, version", __version__))
     r = Zeroconf()
-    print "1. Testing registration of a service..."
+    print("1. Testing registration of a service...")
     desc = {'version':'0.10','a':'test value', 'b':'another value'}
     info = ServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local.", socket.inet_aton("127.0.0.1"), 1234, 0, 0, desc)
-    print "   Registering service..."
+    print("   Registering service...")
     r.registerService(info)
-    print "   Registration done."
-    print "2. Testing query of service information..."
-    print "   Getting ZOE service:", str(r.getServiceInfo("_http._tcp.local.", "ZOE._http._tcp.local."))
-    print "   Query done."
-    print "3. Testing query of own service..."
-    print "   Getting self:", str(r.getServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local."))
-    print "   Query done."
-    print "4. Testing unregister of service information..."
+    print("   Registration done.")
+    print("2. Testing query of service information...")
+    print(("   Getting ZOE service:", str(r.getServiceInfo("_http._tcp.local.", "ZOE._http._tcp.local."))))
+    print("   Query done.")
+    print("3. Testing query of own service...")
+    print(("   Getting self:", str(r.getServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local."))))
+    print("   Query done.")
+    print("4. Testing unregister of service information...")
     r.unregisterService(info)
-    print "   Unregister done."
+    print("   Unregister done.")
     r.close()
diff --git a/testing/mozbase/mozdevice/mozdevice/__init__.py b/testing/mozbase/mozdevice/mozdevice/__init__.py
index 2493f75db2..5e5b3d9881 100644
--- a/testing/mozbase/mozdevice/mozdevice/__init__.py
+++ b/testing/mozbase/mozdevice/mozdevice/__init__.py
@@ -2,13 +2,13 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from adb import ADBError, ADBRootError, ADBTimeoutError, ADBProcess, ADBCommand, ADBHost, ADBDevice
-from adb_android import ADBAndroid
-from adb_b2g import ADBB2G
-from devicemanager import DeviceManager, DMError, ZeroconfListener
-from devicemanagerADB import DeviceManagerADB
-from devicemanagerSUT import DeviceManagerSUT
-from droid import DroidADB, DroidSUT, DroidConnectByHWID
+from .adb import ADBError, ADBRootError, ADBTimeoutError, ADBProcess, ADBCommand, ADBHost, ADBDevice
+from .adb_android import ADBAndroid
+from .adb_b2g import ADBB2G
+from .devicemanager import DeviceManager, DMError, ZeroconfListener
+from .devicemanagerADB import DeviceManagerADB
+from .devicemanagerSUT import DeviceManagerSUT
+from .droid import DroidADB, DroidSUT, DroidConnectByHWID
 
 __all__ = ['ADBError', 'ADBRootError', 'ADBTimeoutError', 'ADBProcess', 'ADBCommand', 'ADBHost',
            'ADBDevice', 'ADBAndroid', 'ADBB2G', 'DeviceManager', 'DMError', 'ZeroconfListener',
diff --git a/testing/mozbase/mozdevice/mozdevice/adb.py b/testing/mozbase/mozdevice/mozdevice/adb.py
index 5958937d9a..5b9ea58ae0 100644
--- a/testing/mozbase/mozdevice/mozdevice/adb.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb.py
@@ -13,9 +13,10 @@ import traceback
 
 from abc import ABCMeta, abstractmethod
 from distutils import dir_util
+import six
 
 
-class ADBProcess(object):
+class ADBProcess:
     """ADBProcess encapsulates the data related to executing the adb process."""
 
     def __init__(self, args):
@@ -43,7 +44,7 @@ class ADBProcess(object):
         return content
 
     def __str__(self):
-        return ('args: %s, exitcode: %s, stdout: %s' % (
+        return ('args: {}, exitcode: {}, stdout: {}'.format(
             ' '.join(self.args), self.exitcode, self.stdout))
 
 # ADBError, ADBRootError, and ADBTimeoutError are treated
@@ -102,7 +103,7 @@ class ADBTimeoutError(Exception):
     pass
 
 
-class ADBCommand(object):
+class ADBCommand:
     """ADBCommand provides a basic interface to adb commands
     which is used to provide the 'command' methods for the
     classes ADBHost and ADBDevice.
@@ -119,7 +120,7 @@ class ADBCommand(object):
        try:
            adbcommand = ADBCommand()
        except NotImplementedError:
-           print "ADBCommand can not be instantiated."
+           print("ADBCommand can not be instantiated.")
     """
 
     def __init__(self,
@@ -153,7 +154,7 @@ class ADBCommand(object):
         self._polling_interval = 0.1
         self._adb_version = ''
 
-        self._logger.debug("%s: %s" % (self.__class__.__name__,
+        self._logger.debug("{}: {}".format(self.__class__.__name__,
                                        self.__dict__))
 
         # catch early a missing or non executable adb command
@@ -165,7 +166,7 @@ class ADBCommand(object):
             re_version = re.compile(r'Android Debug Bridge version (.*)')
             self._adb_version = re_version.match(output[0]).group(1)
         except Exception as exc:
-            raise ADBError('%s: %s is not executable.' % (exc, adb))
+            raise ADBError('{}: {} is not executable.'.format(exc, adb))
 
     def _get_logger(self, logger_name):
         logger = None
@@ -491,13 +492,12 @@ class ADBHost(ADBCommand):
         return devices
 
 
-class ADBDevice(ADBCommand):
+class ADBDevice(six.with_metaclass(ABCMeta, ADBCommand)):
     """ADBDevice is an abstract base class which provides methods which
     can be used to interact with the associated Android or B2G based
     device. It must be used via one of the concrete implementations in
     :class:`ADBAndroid` or :class:`ADBB2G`.
     """
-    __metaclass__ = ABCMeta
 
     def __init__(self,
                  device=None,
@@ -645,7 +645,7 @@ class ADBDevice(ADBCommand):
         def is_valid_serial(serial):
             return ":" not in serial or serial.startswith("usb:")
 
-        if isinstance(device, (str, unicode)):
+        if isinstance(device, (str, str)):
             # Treat this as a device serial
             if not is_valid_serial(device):
                 raise ValueError("Device serials containing ':' characters are "
@@ -1034,10 +1034,10 @@ class ADBDevice(ADBCommand):
 
         # prepend cwd and env to command if necessary
         if cwd:
-            cmd = "cd %s && %s" % (cwd, cmd)
+            cmd = "cd {} && {}".format(cwd, cmd)
         if env:
-            envstr = '&& '.join(map(lambda x: 'export %s=%s' %
-                                    (x[0], x[1]), env.iteritems()))
+            envstr = '&& '.join(['export %s=%s' %
+                                    (x[0], x[1]) for x in env.items()])
             cmd = envstr + "&& " + cmd
         cmd += "; echo rc=$?"
 
@@ -1160,10 +1160,10 @@ class ADBDevice(ADBCommand):
     # Informational methods
 
     def _get_logcat_buffer_args(self, buffers):
-        valid_buffers = set(['radio', 'main', 'events'])
+        valid_buffers = {'radio', 'main', 'events'}
         invalid_buffers = set(buffers).difference(valid_buffers)
         if invalid_buffers:
-            raise ADBError('Invalid logcat buffers %s not in %s ' % (
+            raise ADBError('Invalid logcat buffers {} not in {} '.format(
                 list(invalid_buffers), list(valid_buffers)))
         args = []
         for b in buffers:
@@ -1436,13 +1436,13 @@ class ADBDevice(ADBCommand):
         self._logger.debug('chmod: path=%s, recursive=%s, mask=%s, root=%s' %
                            (path, recursive, mask, root))
         if not recursive:
-            self.shell_output("chmod %s %s" % (mask, path),
+            self.shell_output("chmod {} {}".format(mask, path),
                               timeout=timeout, root=root)
             return
 
         if self._chmod_R:
             try:
-                self.shell_output("chmod -R %s %s" % (mask, path),
+                self.shell_output("chmod -R {} {}".format(mask, path),
                                   timeout=timeout, root=root)
             except ADBError as e:
                 if e.message.find('No such file or directory') == -1:
@@ -1460,7 +1460,7 @@ class ADBDevice(ADBCommand):
         try:
             tmpf = tempfile.NamedTemporaryFile(delete=False)
             for entry in entries:
-                tmpf.write('chmod %s %s\n' % (mask, entry))
+                tmpf.write('chmod {} {}\n'.format(mask, entry))
             tmpf.close()
             chmodsh = '/data/local/tmp/%s' % os.path.basename(tmpf.name)
             self.push(tmpf.name, chmodsh)
@@ -1560,7 +1560,7 @@ class ADBDevice(ADBCommand):
         data = []
         if self.is_dir(path, timeout=timeout, root=root):
             try:
-                data = self.shell_output("%s %s" % (self._ls, path),
+                data = self.shell_output("{} {}".format(self._ls, path),
                                          timeout=timeout,
                                          root=root).split('\r\n')
                 self._logger.debug('list_files: data: %s' % data)
@@ -1632,7 +1632,7 @@ class ADBDevice(ADBCommand):
                                           root=root)
                 if model == 'Nexus 4':
                     path += '*'
-        lines = self.shell_output('%s %s %s' % (self._ls, recursive_flag, path),
+        lines = self.shell_output('{} {} {}'.format(self._ls, recursive_flag, path),
                                   timeout=timeout,
                                   root=root).split('\r\n')
         for line in lines:
@@ -1647,11 +1647,11 @@ class ADBDevice(ADBCommand):
                 if parent[:-1] in entries:
                     del entries[parent[:-1]]
             elif parent:
-                entry = "%s%s" % (parent, line)
+                entry = "{}{}".format(parent, line)
             else:
                 entry = line
             entries[entry] = 1
-        entry_list = entries.keys()
+        entry_list = list(entries.keys())
         entry_list.sort()
         return entry_list
 
@@ -1841,7 +1841,7 @@ class ADBDevice(ADBCommand):
         if recursive:
             cmd += " -r"
         try:
-            self.shell_output("%s %s" % (cmd, path), timeout=timeout, root=root)
+            self.shell_output("{} {}".format(cmd, path), timeout=timeout, root=root)
             if self.is_file(path, timeout=timeout, root=root):
                 raise ADBError('rm("%s") failed to remove file.' % path)
         except ADBError as e:
@@ -1907,7 +1907,7 @@ class ADBDevice(ADBCommand):
                     pid_i = i
             if user_i == -1 or pid_i == -1:
                 self._logger.error('get_process_list: %s' % header)
-                raise ADBError('get_process_list: Unknown format: %s: %s' % (
+                raise ADBError('get_process_list: Unknown format: {}: {}'.format(
                     header, adb_process))
             ret = []
             line = adb_process.stdout_file.readline()
@@ -1916,9 +1916,9 @@ class ADBDevice(ADBCommand):
                 try:
                     ret.append([int(els[pid_i]), els[-1], els[user_i]])
                 except ValueError:
-                    self._logger.error('get_process_list: %s %s\n%s' % (
+                    self._logger.error('get_process_list: {} {}\n{}'.format(
                         header, line, traceback.format_exc()))
-                    raise ADBError('get_process_list: %s: %s: %s' % (
+                    raise ADBError('get_process_list: {}: {}: {}'.format(
                         header, line, adb_process))
                 line = adb_process.stdout_file.readline()
             self._logger.debug('get_process_list: %s' % ret)
@@ -1962,8 +1962,8 @@ class ADBDevice(ADBCommand):
                 if 'No such process' not in e.message:
                     raise
             pid_set = set(pid_list)
-            current_pid_set = set([str(proc[0]) for proc in
-                                   self.get_process_list(timeout=timeout)])
+            current_pid_set = {str(proc[0]) for proc in
+                                   self.get_process_list(timeout=timeout)}
             pid_list = list(pid_set.intersection(current_pid_set))
             if not pid_list:
                 break
@@ -2033,7 +2033,7 @@ class ADBDevice(ADBCommand):
         :raises: * ADBTimeoutError
                  * ADBError
         """
-        if not isinstance(process_name, basestring):
+        if not isinstance(process_name, str):
             raise ADBError("Process name %s is not a string" % process_name)
 
         # Filter out extra spaces.
@@ -2087,7 +2087,7 @@ class ADBDevice(ADBCommand):
         destination = posixpath.normpath(destination)
         if self._have_cp:
             r = '-R' if recursive else ''
-            self.shell_output('cp %s %s %s' % (r, source, destination),
+            self.shell_output('cp {} {} {}'.format(r, source, destination),
                               timeout=timeout, root=root)
             return
 
@@ -2102,7 +2102,7 @@ class ADBDevice(ADBCommand):
                 # Copy the source file into the destination directory
                 destination = posixpath.join(destination,
                                              posixpath.basename(source))
-            self.shell_output('dd if=%s of=%s' % (source, destination),
+            self.shell_output('dd if={} of={}'.format(source, destination),
                               timeout=timeout, root=root)
             return
 
@@ -2153,7 +2153,7 @@ class ADBDevice(ADBCommand):
         """
         source = posixpath.normpath(source)
         destination = posixpath.normpath(destination)
-        self.shell_output('mv %s %s' % (source, destination), timeout=timeout,
+        self.shell_output('mv {} {}'.format(source, destination), timeout=timeout,
                           root=root)
 
     def reboot(self, timeout=None):
diff --git a/testing/mozbase/mozdevice/mozdevice/adb_android.py b/testing/mozbase/mozdevice/mozdevice/adb_android.py
index bf5fffc0e5..51f4fcd82a 100644
--- a/testing/mozbase/mozdevice/mozdevice/adb_android.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb_android.py
@@ -8,12 +8,13 @@ import time
 
 from abc import ABCMeta
 
-import version_codes
+from . import version_codes
 
-from adb import ADBDevice, ADBError
+from .adb import ADBDevice, ADBError
+import six
 
 
-class ADBAndroid(ADBDevice):
+class ADBAndroid(six.with_metaclass(ABCMeta, ADBDevice)):
     """ADBAndroid implements :class:`ADBDevice` providing Android-specific
     functionality.
 
@@ -22,11 +23,10 @@ class ADBAndroid(ADBDevice):
        from mozdevice import ADBAndroid
 
        adbdevice = ADBAndroid()
-       print adbdevice.list_files("/mnt/sdcard")
+       print(adbdevice.list_files("/mnt/sdcard"))
        if adbdevice.process_exist("org.mozilla.fennec"):
-           print "Fennec is running"
+           print("Fennec is running")
     """
-    __metaclass__ = ABCMeta
 
     def __init__(self,
                  device=None,
@@ -220,7 +220,7 @@ class ADBAndroid(ADBDevice):
                 failure = e.message
 
             if not success:
-                self._logger.debug('Attempt %s of %s device not ready: %s' % (
+                self._logger.debug('Attempt {} of {} device not ready: {}'.format(
                     attempt + 1, self._device_ready_retry_attempts,
                     failure))
                 time.sleep(self._device_ready_retry_wait)
@@ -333,13 +333,13 @@ class ADBAndroid(ADBDevice):
                            "at once")
 
         acmd = ["am", "start"] + \
-            ["-W" if wait else '', "-n", "%s/%s" % (app_name, activity_name)]
+            ["-W" if wait else '', "-n", "{}/{}".format(app_name, activity_name)]
 
         if intent:
             acmd.extend(["-a", intent])
 
         if extras:
-            for (key, val) in extras.iteritems():
+            for (key, val) in extras.items():
                 if isinstance(val, int):
                     extra_type_param = "--ei"
                 elif isinstance(val, bool):
@@ -389,7 +389,7 @@ class ADBAndroid(ADBDevice):
         if moz_env:
             # moz_env is expected to be a dictionary of environment variables:
             # Fennec itself will set them when launched
-            for (env_count, (env_key, env_val)) in enumerate(moz_env.iteritems()):
+            for (env_count, (env_key, env_val)) in enumerate(moz_env.items()):
                 extras["env" + str(env_count)] = env_key + "=" + env_val
 
         # Additional command line arguments that fennec will read and use (e.g.
@@ -465,7 +465,7 @@ class ADBAndroid(ADBDevice):
             data = self.command_output(["uninstall", app_name], timeout=timeout)
             if data.find('Success') == -1:
                 self._logger.debug('uninstall_app failed: %s' % data)
-                raise ADBError("uninstall failed for %s. Got: %s" % (app_name, data))
+                raise ADBError("uninstall failed for {}. Got: {}".format(app_name, data))
             if reboot:
                 self.reboot(timeout=timeout)
 
diff --git a/testing/mozbase/mozdevice/mozdevice/adb_b2g.py b/testing/mozbase/mozdevice/mozdevice/adb_b2g.py
index 3280e61720..88226e551a 100644
--- a/testing/mozbase/mozdevice/mozdevice/adb_b2g.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb_b2g.py
@@ -6,7 +6,7 @@ import traceback
 
 import mozfile
 
-from adb import ADBDevice, ADBError
+from .adb import ADBDevice, ADBError
 
 
 class ADBB2G(ADBDevice):
@@ -18,9 +18,9 @@ class ADBB2G(ADBDevice):
        from mozdevice import ADBB2G
 
        adbdevice = ADBB2G()
-       print adbdevice.list_files("/mnt/sdcard")
+       print(adbdevice.list_files("/mnt/sdcard"))
        if adbdevice.process_exist("b2g"):
-           print "B2G is running"
+           print("B2G is running")
     """
 
     def get_battery_percentage(self, timeout=None):
@@ -96,7 +96,7 @@ class ADBB2G(ADBDevice):
         :raises: * ADBTimeoutError
                  * ADBError
         """
-        info = super(ADBB2G, self).get_info(directive=directive,
+        info = super().get_info(directive=directive,
                                             timeout=timeout)
 
         directives = ['memtotal']
diff --git a/testing/mozbase/mozdevice/mozdevice/devicemanager.py b/testing/mozbase/mozdevice/mozdevice/devicemanager.py
index de87735ef5..0f07880699 100644
--- a/testing/mozbase/mozdevice/mozdevice/devicemanager.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanager.py
@@ -27,8 +27,8 @@ class DMError(Exception):
 
 
 def abstractmethod(method):
-    line = method.func_code.co_firstlineno
-    filename = method.func_code.co_filename
+    line = method.__code__.co_firstlineno
+    filename = method.__code__.co_filename
 
     @wraps(method)
     def not_implemented(*args, **kwargs):
@@ -38,7 +38,7 @@ def abstractmethod(method):
     return not_implemented
 
 
-class DeviceManager(object):
+class DeviceManager:
     """
     Represents a connection to a device. Once an implementation of this class
     is successfully instantiated, you may do things like list/copy files to
@@ -250,7 +250,7 @@ class DeviceManager(object):
         Returns True if remoteDirname on device is same as localDirname on host.
         """
 
-        self._logger.info("validating directory: %s to %s" % (localDirname, remoteDirname))
+        self._logger.info("validating directory: {} to {}".format(localDirname, remoteDirname))
         for root, dirs, files in os.walk(localDirname):
             parts = root.split(localDirname)
             for f in files:
@@ -428,13 +428,13 @@ class DeviceManager(object):
         Information on process is in tuple format: (pid, process path, user)
         If a process with the specified name does not exist this function will return None.
         """
-        if not isinstance(processName, basestring):
+        if not isinstance(processName, str):
             raise TypeError("Process name %s is not a string" % processName)
 
         processInfo = None
 
         # filter out extra spaces
-        parts = filter(lambda x: x != '', processName.split(' '))
+        parts = [x for x in processName.split(' ') if x != '']
         processName = ' '.join(parts)
 
         # filter out the quoted env string if it exists
@@ -593,7 +593,7 @@ class DeviceManager(object):
         quotedCmd = []
 
         for arg in cmd:
-            arg.replace('&', '\&')
+            arg.replace('&', r'\&')
 
             needsQuoting = False
             for char in [' ', '(', ')', '"', '&']:
@@ -641,7 +641,7 @@ def _pop_last_line(file_obj):
     return None
 
 
-class ZeroconfListener(object):
+class ZeroconfListener:
 
     def __init__(self, hwid, evt):
         self.hwid = hwid
@@ -654,13 +654,13 @@ class ZeroconfListener(object):
             return
 
         sutname = name.split('.')[0]
-        m = re.search('\[hwid:([^\]]*)\]', sutname)
+        m = re.search(r'\[hwid:([^\]]*)\]', sutname)
         if m is None:
             return
 
         hwid = m.group(1)
 
-        m = re.search('\[ip:([0-9_]*)\]', sutname)
+        m = re.search(r'\[ip:([0-9_]*)\]', sutname)
         if m is None:
             return
 
diff --git a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
index 74d0a8d23f..ecfe430f99 100644
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
@@ -11,10 +11,10 @@ import traceback
 
 from distutils import dir_util
 
-from devicemanager import DeviceManager, DMError
+from .devicemanager import DeviceManager, DMError
 from mozprocess import ProcessHandler
 import mozfile
-import version_codes
+from . import version_codes
 
 
 class DeviceManagerADB(DeviceManager):
@@ -130,7 +130,7 @@ class DeviceManagerADB(DeviceManager):
         # doesn't actually return the return code from a process, so we have to
         # capture the output to get it
         if root and self._haveSu:
-            cmdline = "su %s \"%s\"" % (self._suModifier,
+            cmdline = "su {} \"{}\"".format(self._suModifier,
                                         self._escapedCommandLine(cmd))
         else:
             cmdline = self._escapedCommandLine(cmd)
@@ -138,9 +138,9 @@ class DeviceManagerADB(DeviceManager):
 
         # prepend cwd and env to command if necessary
         if cwd:
-            cmdline = "cd %s; %s" % (cwd, cmdline)
+            cmdline = "cd {}; {}".format(cwd, cmdline)
         if env:
-            envstr = '; '.join(map(lambda x: 'export %s=%s' % (x[0], x[1]), env.iteritems()))
+            envstr = '; '.join(['export {}={}'.format(x[0], x[1]) for x in env.items()])
             cmdline = envstr + "; " + cmdline
 
         # all output should be in stdout
@@ -444,7 +444,7 @@ class DeviceManagerADB(DeviceManager):
         if env != '' and env is not None:
             envCnt = 0
             # env is expected to be a dict of environment variables
-            for envkey, envval in env.iteritems():
+            for envkey, envval in env.items():
                 acmd.append("--es")
                 acmd.append("env" + str(envCnt))
                 acmd.append(envkey + "=" + envval)
@@ -453,7 +453,7 @@ class DeviceManagerADB(DeviceManager):
             acmd.append("-d")
             acmd.append(uri)
 
-        acmd = ["shell", ' '.join(map(lambda x: '"' + x + '"', ["am", "start"] + acmd))]
+        acmd = ["shell", ' '.join(['"' + x + '"' for x in ["am", "start"] + acmd])]
         self._logger.info(acmd)
         self._checkCmd(acmd)
         return outputFile
@@ -494,7 +494,7 @@ class DeviceManagerADB(DeviceManager):
         try:
             self._runCmd(["pull",  remoteFile, localFile])
         except (OSError, ValueError):
-            raise DMError("Error pulling remote file '%s' to '%s'" % (remoteFile, localFile))
+            raise DMError("Error pulling remote file '{}' to '{}'".format(remoteFile, localFile))
 
     def pullFile(self, remoteFile, offset=None, length=None):
         # TODO: add debug flags and allow for printing stdout
@@ -628,7 +628,7 @@ class DeviceManagerADB(DeviceManager):
             uptime = self.shellCheckOutput(["uptime"], timeout=self.short_timeout)
             if not uptime:
                 raise DMError("error getting uptime")
-            m = re.match("up time: ((\d+) days, )*(\d{2}):(\d{2}):(\d{2})", uptime)
+            m = re.match(r"up time: ((\d+) days, )*(\d{2}):(\d{2}):(\d{2})", uptime)
             if m:
                 uptime = "%d days %d hours %d minutes %d seconds" % tuple(
                     [int(g or 0) for g in m.groups()[1:]])
@@ -654,7 +654,7 @@ class DeviceManagerADB(DeviceManager):
     def uninstallApp(self, appName, installPath=None):
         status = self._runCmd(["uninstall", appName]).output[0].strip()
         if status != 'Success':
-            raise DMError("uninstall failed for %s. Got: %s" % (appName, status))
+            raise DMError("uninstall failed for {}. Got: {}".format(appName, status))
 
     def uninstallAppAndReboot(self, appName, installPath=None):
         self.uninstallApp(appName)
@@ -769,7 +769,7 @@ class DeviceManagerADB(DeviceManager):
             proc = self._runCmd(["version"], timeout=self.short_timeout)
             self._adb_version = re_version.match(proc.output[0]).group(1)
             self._logger.info("Detected adb %s" % self._adb_version)
-        except os.error as err:
+        except OSError as err:
             raise DMError(
                 "unable to execute ADB (%s): ensure Android SDK is installed "
                 "and adb is in your $PATH" % err)
@@ -779,14 +779,14 @@ class DeviceManagerADB(DeviceManager):
         if self._deviceSerial:
             deviceStatus = None
             for line in self._runCmd(["devices"]).output:
-                m = re.match('(.+)?\s+(.+)$', line)
+                m = re.match(r'(.+)?\s+(.+)$', line)
                 if m:
                     if self._deviceSerial == m.group(1):
                         deviceStatus = m.group(2)
             if deviceStatus is None:
                 raise DMError("device not found: %s" % self._deviceSerial)
             elif deviceStatus != "device":
-                raise DMError("bad status for device %s: %s" % (self._deviceSerial, deviceStatus))
+                raise DMError("bad status for device {}: {}".format(self._deviceSerial, deviceStatus))
 
         # Check to see if we can connect to device and run a simple command
         if not self._checkCmd(["shell", "echo"], timeout=self.short_timeout) == 0:
diff --git a/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py b/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
index 7816a3fdda..a1df5f7798 100644
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
@@ -13,7 +13,7 @@ import re
 import posixpath
 import subprocess
 import StringIO
-from devicemanager import DeviceManager, DMError, _pop_last_line
+from .devicemanager import DeviceManager, DMError, _pop_last_line
 import errno
 from distutils.version import StrictVersion
 
@@ -27,10 +27,10 @@ class DeviceManagerSUT(DeviceManager):
     """
 
     _base_prompt = '$>'
-    _base_prompt_re = '\$\>'
+    _base_prompt_re = r'\$\>'
     _prompt_sep = '\x00'
     _prompt_regex = '.*(' + _base_prompt_re + _prompt_sep + ')'
-    _agentErrorRE = re.compile('^##AGENT-WARNING##\ ?(.*)')
+    _agentErrorRE = re.compile(r'^##AGENT-WARNING##\ ?(.*)')
 
     reboot_timeout = 600
     reboot_settling_time = 60
@@ -47,7 +47,7 @@ class DeviceManagerSUT(DeviceManager):
 
         # Get version
         verstring = self._runCmds([{'cmd': 'ver'}])
-        ver_re = re.match('(\S+) Version (\S+)', verstring)
+        ver_re = re.match(r'(\S+) Version (\S+)', verstring)
         self.agentProductName = ver_re.group(1)
         self.agentVersion = ver_re.group(2)
 
@@ -167,7 +167,7 @@ class DeviceManagerSUT(DeviceManager):
                 if self._everConnected:
                     self._logger.info("reconnecting socket")
                 self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            except socket.error as msg:
+            except OSError as msg:
                 self._sock = None
                 raise DMError("Automation Error: unable to create socket: " + str(msg))
 
@@ -175,14 +175,14 @@ class DeviceManagerSUT(DeviceManager):
                 self._sock.settimeout(float(timeout))
                 self._sock.connect((self.host, int(self.port)))
                 self._everConnected = True
-            except socket.error as msg:
+            except OSError as msg:
                 self._sock = None
                 raise DMError("Remote Device Error: Unable to connect socket: " + str(msg))
 
             # consume prompt
             try:
                 self._sock.recv(1024)
-            except socket.error as msg:
+            except OSError as msg:
                 self._sock.close()
                 self._sock = None
                 raise DMError(
@@ -210,7 +210,7 @@ class DeviceManagerSUT(DeviceManager):
                         totalsent += sent
 
                 self._logger.debug("sent cmd: %s" % cmd['cmd'])
-            except socket.error as msg:
+            except OSError as msg:
                 self._sock.close()
                 self._sock = None
                 self._logger.error("Remote Device Error: Error sending data"
@@ -239,7 +239,7 @@ class DeviceManagerSUT(DeviceManager):
                         # Wait up to a second for socket to become ready for reading...
                         if select.select([self._sock], [], [], select_timeout)[0]:
                             temp = self._sock.recv(1024)
-                            self._logger.debug(u"response: %s" % temp.decode('utf8', 'replace'))
+                            self._logger.debug("response: %s" % temp.decode('utf8', 'replace'))
                             timer = 0
                             if not temp:
                                 socketClosed = True
@@ -250,7 +250,7 @@ class DeviceManagerSUT(DeviceManager):
                             self._sock = None
                             raise DMError("Automation Error: Timeout in command %s" %
                                           cmd['cmd'], fatal=True)
-                    except socket.error as err:
+                    except OSError as err:
                         socketClosed = True
                         errStr = str(err)
                         # This error shows up with we have our tegra rebooted.
@@ -313,7 +313,7 @@ class DeviceManagerSUT(DeviceManager):
     def shell(self, cmd, outputfile, env=None, cwd=None, timeout=None, root=False):
         cmdline = self._escapedCommandLine(cmd)
         if env:
-            cmdline = '%s %s' % (self._formatEnvString(env), cmdline)
+            cmdline = '{} {}'.format(self._formatEnvString(env), cmdline)
 
         # execcwd/execcwdsu currently unsupported in Negatus; see bug 824127.
         if cwd and self.agentProductName == 'SUTAgentNegatus':
@@ -335,22 +335,22 @@ class DeviceManagerSUT(DeviceManager):
             cmd += "su"
 
         if cwd:
-            self._sendCmds([{'cmd': '%s %s %s' % (cmd, cwd, cmdline)}], outputfile, timeout)
+            self._sendCmds([{'cmd': '{} {} {}'.format(cmd, cwd, cmdline)}], outputfile, timeout)
         else:
             if (not root) or haveExecSu:
-                self._sendCmds([{'cmd': '%s %s' % (cmd, cmdline)}], outputfile, timeout)
+                self._sendCmds([{'cmd': '{} {}'.format(cmd, cmdline)}], outputfile, timeout)
             else:
                 # need to manually inject su -c for backwards compatibility (this may
                 # not work on ICS or above!!)
                 # (FIXME: this backwards compatibility code is really ugly and should
                 # be deprecated at some point in the future)
-                self._sendCmds([{'cmd': '%s su -c "%s"' % (cmd, cmdline)}], outputfile,
+                self._sendCmds([{'cmd': '{} su -c "{}"'.format(cmd, cmdline)}], outputfile,
                                timeout)
 
         # dig through the output to get the return code
         lastline = _pop_last_line(outputfile)
         if lastline:
-            m = re.search('return code \[([0-9]+)\]', lastline)
+            m = re.search(r'return code \[([0-9]+)\]', lastline)
             if m:
                 return int(m.group(1))
 
@@ -385,7 +385,7 @@ class DeviceManagerSUT(DeviceManager):
 
     def pushDir(self, localDir, remoteDir, retryLimit=None, timeout=None):
         retryLimit = retryLimit or self.retryLimit
-        self._logger.info("pushing directory: %s to %s" % (localDir, remoteDir))
+        self._logger.info("pushing directory: {} to {}".format(localDir, remoteDir))
 
         existentDirectories = []
         for root, dirs, files in os.walk(localDir, followlinks=True):
@@ -430,7 +430,7 @@ class DeviceManagerSUT(DeviceManager):
             return []
         data = self._runCmds([{'cmd': 'cd ' + rootdir}, {'cmd': 'ls'}])
 
-        files = filter(lambda x: x, data.splitlines())
+        files = [x for x in data.splitlines() if x]
         if len(files) == 1 and files[0] == '':
             # special case on the agent: empty directories return just the
             # string ""
@@ -447,10 +447,10 @@ class DeviceManagerSUT(DeviceManager):
             self._runCmds([{'cmd': 'rmdr ' + remoteDir}])
 
     def moveTree(self, source, destination):
-        self._runCmds([{'cmd': 'mv %s %s' % (source, destination)}])
+        self._runCmds([{'cmd': 'mv {} {}'.format(source, destination)}])
 
     def copyTree(self, source, destination):
-        self._runCmds([{'cmd': 'dd if=%s of=%s' % (source, destination)}])
+        self._runCmds([{'cmd': 'dd if={} of={}'.format(source, destination)}])
 
     def getProcessList(self):
         data = self._runCmds([{'cmd': 'ps'}])
@@ -470,7 +470,7 @@ class DeviceManagerSUT(DeviceManager):
                         raise ValueError
                 except ValueError:
                     self._logger.error("Unable to parse process list (bug 805969)")
-                    self._logger.error("Line: %s\nFull output of process list:\n%s" % (line, data))
+                    self._logger.error("Line: {}\nFull output of process list:\n{}".format(line, data))
                     raise DMError("Invalid process line: %s" % line)
 
         return processTuples
@@ -508,7 +508,7 @@ class DeviceManagerSUT(DeviceManager):
             time.sleep(1)
             waited += 1
 
-        self._logger.debug("got pid: %s for process: %s" % (pid, appname))
+        self._logger.debug("got pid: {} for process: {}".format(pid, appname))
         return pid
 
     def launchProcess(self, cmd, outputFile="process.txt", cwd='', env='', failIfRunning=False):
@@ -535,7 +535,7 @@ class DeviceManagerSUT(DeviceManager):
             cmdline += " > " + outputFile
 
         # Prepend our env to the command
-        cmdline = '%s %s' % (self._formatEnvString(env), cmdline)
+        cmdline = '{} {}'.format(self._formatEnvString(env), cmdline)
 
         # fireProcess may trigger an exception, but we won't handle it
         if cmd[0] == "am":
@@ -740,7 +740,7 @@ class DeviceManagerSUT(DeviceManager):
         if destDir[-1] != '/':
             destDir += '/'
 
-        self._runCmds([{'cmd': 'unzp %s %s' % (filePath, destDir)}])
+        self._runCmds([{'cmd': 'unzp {} {}'.format(filePath, destDir)}])
 
     def _getRebootServerSocket(self, ipAddr):
         serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -770,7 +770,7 @@ class DeviceManagerSUT(DeviceManager):
                 conn.close()
             except socket.timeout:
                 pass
-            except socket.error as e:
+            except OSError as e:
                 if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
                     raise
 
@@ -803,7 +803,7 @@ class DeviceManagerSUT(DeviceManager):
             # after restarting.
             destname = '/data/data/com.mozilla.SUTAgentAndroid/files/update.info'
             data = "%s,%s\rrebooting\r" % serverSocket.getsockname()
-            self._runCmds([{'cmd': 'push %s %s' % (destname, len(data)),
+            self._runCmds([{'cmd': 'push {} {}'.format(destname, len(data)),
                             'data': data}])
             cmd += " %s %s" % serverSocket.getsockname()
 
@@ -832,8 +832,8 @@ class DeviceManagerSUT(DeviceManager):
             result[d] = data.split('\n')
 
         # Get rid of any 0 length members of the arrays
-        for k, v in result.iteritems():
-            result[k] = filter(lambda x: x != '', result[k])
+        for k, v in result.items():
+            result[k] = [x for x in result[k] if x != '']
 
         # Format the process output
         if 'process' in result:
@@ -920,7 +920,7 @@ class DeviceManagerSUT(DeviceManager):
         if (env is None or env == ''):
             return ''
 
-        retVal = '"%s"' % ','.join(map(lambda x: '%s=%s' % (x[0], x[1]), env.iteritems()))
+        retVal = '"%s"' % ','.join(['{}={}'.format(x[0], x[1]) for x in env.items()])
         if (retVal == '""'):
             return ''
 
@@ -964,12 +964,12 @@ class DeviceManagerSUT(DeviceManager):
         if (height < 100 or height > 9999):
             return False
 
-        self._logger.debug("adjusting screen resolution to %s, %s and rebooting" % (width, height))
+        self._logger.debug("adjusting screen resolution to {}, {} and rebooting".format(width, height))
 
         self._runCmds(
-            [{'cmd': "exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)}])
+            [{'cmd': "exec setprop persist.tegra.dpy{}.mode.width {}".format(screentype, width)}])
         self._runCmds(
-            [{'cmd': "exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)}])
+            [{'cmd': "exec setprop persist.tegra.dpy{}.mode.height {}".format(screentype, height)}])
 
     def chmodDir(self, remoteDir, **kwargs):
         self._runCmds([{'cmd': "chmod " + remoteDir}])
diff --git a/testing/mozbase/mozdevice/mozdevice/dmcli.py b/testing/mozbase/mozdevice/mozdevice/dmcli.py
index 7ba65e8426..f9d13ea23b 100644
--- a/testing/mozbase/mozdevice/mozdevice/dmcli.py
+++ b/testing/mozbase/mozdevice/mozdevice/dmcli.py
@@ -6,6 +6,7 @@
 Command-line client to control a device
 """
 
+from __future__ import print_function
 import errno
 import logging
 import os
@@ -190,7 +191,7 @@ class DMCli(object):
 
     def add_commands(self, parser):
         subparsers = parser.add_subparsers(title="Commands", metavar="")
-        for (commandname, commandprops) in sorted(self.commands.iteritems()):
+        for (commandname, commandprops) in sorted(self.commands.items()):
             subparser = subparsers.add_parser(commandname, help=commandprops['help'])
             if commandprops.get('args'):
                 for arg in commandprops['args']:
@@ -234,7 +235,7 @@ class DMCli(object):
             self.parser.error("Unknown device manager type: %s" % type)
 
     def deviceroot(self, args):
-        print self.dm.deviceRoot
+        print(self.dm.deviceRoot)
 
     def push(self, args):
         (src, dest) = (args.local_file, args.remote_file)
@@ -250,7 +251,7 @@ class DMCli(object):
     def pull(self, args):
         (src, dest) = (args.local_file, args.remote_file)
         if not self.dm.fileExists(src):
-            print 'No such file or directory'
+            print('No such file or directory')
             return
         if not dest:
             dest = posixpath.basename(src)
@@ -276,7 +277,7 @@ class DMCli(object):
 
     def listapps(self, args):
         for app in self.dm.getInstalledApps():
-            print app
+            print(app)
 
     def stopapp(self, args):
         self.dm.stopApplication(args.appname)
@@ -288,20 +289,20 @@ class DMCli(object):
     def shell(self, args):
         buf = StringIO.StringIO()
         self.dm.shell(args.command, buf, root=args.root)
-        print str(buf.getvalue()[0:-1]).rstrip()
+        print(str(buf.getvalue()[0:-1]).rstrip())
 
     def getinfo(self, args):
         info = self.dm.getInfo(directive=args.directive)
-        for (infokey, infoitem) in sorted(info.iteritems()):
+        for (infokey, infoitem) in sorted(info.items()):
             if infokey == "process":
                 pass  # skip process list: get that through ps
             elif args.directive is None:
-                print "%s: %s" % (infokey.upper(), infoitem)
+                print("%s: %s" % (infokey.upper(), infoitem))
             else:
-                print infoitem
+                print(infoitem)
 
     def logcat(self, args):
-        print ''.join(self.dm.getLogcat())
+        print(''.join(self.dm.getLogcat()))
 
     def clearlogcat(self, args):
         self.dm.recordLogcat()
@@ -312,22 +313,22 @@ class DMCli(object):
     def processlist(self, args):
         pslist = self.dm.getProcessList()
         for ps in pslist:
-            print " ".join(str(i) for i in ps)
+            print(" ".join(str(i) for i in ps))
 
     def listfiles(self, args):
         filelist = self.dm.listFiles(args.remote_dir)
         for file in filelist:
-            print file
+            print(file)
 
     def removefile(self, args):
         self.dm.removeFile(args.remote_file)
 
     def isdir(self, args):
         if self.dm.dirExists(args.remote_dir):
-            print "TRUE"
+            print("TRUE")
             return
 
-        print "FALSE"
+        print("FALSE")
         return errno.ENOTDIR
 
     def mkdir(self, args):
@@ -341,16 +342,16 @@ class DMCli(object):
 
     def sutver(self, args):
         if args.dmtype == 'sut':
-            print '%s Version %s' % (self.dm.agentProductName,
-                                     self.dm.agentVersion)
+            print('%s Version %s' % (self.dm.agentProductName,
+                                     self.dm.agentVersion))
         else:
-            print 'Must use SUT transport to get SUT version.'
+            print('Must use SUT transport to get SUT version.')
 
     def isfile(self, args):
         if self.dm.fileExists(args.remote_file):
-            print "TRUE"
+            print("TRUE")
             return
-        print "FALSE"
+        print("FALSE")
         return errno.ENOENT
 
     def launchfennec(self, args):
@@ -368,9 +369,9 @@ class DMCli(object):
 
     def getip(self, args):
         if args.interface:
-            print(self.dm.getIP(args.interface))
+            print((self.dm.getIP(args.interface)))
         else:
-            print(self.dm.getIP())
+            print((self.dm.getIP()))
 
 
 def cli(args=sys.argv[1:]):
diff --git a/testing/mozbase/mozdevice/mozdevice/droid.py b/testing/mozbase/mozdevice/mozdevice/droid.py
index f06a619c44..3f9f138d32 100644
--- a/testing/mozbase/mozdevice/mozdevice/droid.py
+++ b/testing/mozbase/mozdevice/mozdevice/droid.py
@@ -2,19 +2,20 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import StringIO
 import moznetwork
 import re
 import threading
 import time
 
-import version_codes
+from . import version_codes
 
-from Zeroconf import Zeroconf, ServiceBrowser
-from devicemanager import ZeroconfListener
-from devicemanagerADB import DeviceManagerADB
-from devicemanagerSUT import DeviceManagerSUT
-from devicemanager import DMError
+from .Zeroconf import Zeroconf, ServiceBrowser
+from .devicemanager import ZeroconfListener
+from .devicemanagerADB import DeviceManagerADB
+from .devicemanagerSUT import DeviceManagerSUT
+from .devicemanager import DMError
 
 
 class DroidMixin(object):
@@ -54,7 +55,7 @@ class DroidMixin(object):
             acmd.extend(["-a", intent])
 
         if extras:
-            for (key, val) in extras.iteritems():
+            for (key, val) in extras.items():
                 if type(val) is int:
                     extraTypeParam = "--ei"
                 elif type(val) is bool:
@@ -96,7 +97,7 @@ class DroidMixin(object):
         if mozEnv:
             # mozEnv is expected to be a dictionary of environment variables: Fennec
             # itself will set them when launched
-            for (envCnt, (envkey, envval)) in enumerate(mozEnv.iteritems()):
+            for (envCnt, (envkey, envval)) in enumerate(mozEnv.items()):
                 extras["env" + str(envCnt)] = envkey + "=" + envval
 
         # Additional command line arguments that fennec will read and use (e.g.
@@ -181,7 +182,7 @@ class DroidADB(DeviceManagerADB, DroidMixin):
         if m:
             line = m.group(0)
             # Extract package name: string of non-whitespace ending in forward slash
-            m = re.search('(\S+)/$', line)
+            m = re.search(r'(\S+)/$', line)
             if m:
                 package = m.group(1)
         if not package:
@@ -251,7 +252,7 @@ def DroidConnectByHWID(hwid, timeout=30, **kwargs):
 
     if foundIP is not None:
         return DroidSUT(foundIP, **kwargs)
-    print "Connected via SUT to %s [at %s]" % (hwid, foundIP)
+    print("Connected via SUT to %s [at %s]" % (hwid, foundIP))
 
     # try connecting via adb
     try:
@@ -259,5 +260,5 @@ def DroidConnectByHWID(hwid, timeout=30, **kwargs):
     except:
         return None
 
-    print "Connected via ADB to %s" % (hwid)
+    print("Connected via ADB to %s" % (hwid))
     return sut
diff --git a/testing/mozbase/mozdevice/mozdevice/sutini.py b/testing/mozbase/mozdevice/mozdevice/sutini.py
index 7dd5e54c4a..e9cb725b52 100644
--- a/testing/mozbase/mozdevice/mozdevice/sutini.py
+++ b/testing/mozbase/mozdevice/mozdevice/sutini.py
@@ -2,7 +2,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import ConfigParser
+from __future__ import print_function
+import six.moves.configparser
 import StringIO
 import os
 import sys
@@ -10,6 +11,7 @@ import tempfile
 
 from mozdevice.droid import DroidSUT
 from mozdevice.devicemanager import DMError
+import six
 
 USAGE = '%s '
 INI_PATH_JAVA = '/data/data/com.mozilla.SUTAgentAndroid/files/SUTAgent.ini'
@@ -25,7 +27,7 @@ SCHEMA = {'Registration Server': (('IPAddr', ''),
 
 
 def get_cfg(d, ini_path):
-    cfg = ConfigParser.RawConfigParser()
+    cfg = six.moves.configparser.RawConfigParser()
     try:
         cfg.readfp(StringIO.StringIO(d.pullFile(ini_path)), 'SUTAgent.ini')
     except DMError:
@@ -35,16 +37,16 @@ def get_cfg(d, ini_path):
 
 
 def put_cfg(d, cfg, ini_path):
-    print 'Writing modified SUTAgent.ini...'
+    print('Writing modified SUTAgent.ini...')
     t = tempfile.NamedTemporaryFile(delete=False)
     cfg.write(t)
     t.close()
     try:
         d.pushFile(t.name, ini_path)
-    except DMError, e:
-        print e
+    except DMError as e:
+        print(e)
     else:
-        print 'Done.'
+        print('Done.')
     finally:
         os.unlink(t.name)
 
@@ -53,14 +55,14 @@ def set_opt(cfg, s, o, dflt):
     prompt = '  %s' % o
     try:
         curval = cfg.get(s, o)
-    except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
+    except (six.moves.configparser.NoSectionError, six.moves.configparser.NoOptionError):
         curval = ''
     if curval:
         dflt = curval
     prompt += ': '
     if dflt:
         prompt += '[%s] ' % dflt
-    newval = raw_input(prompt)
+    newval = input(prompt)
     if not newval:
         newval = dflt
     if newval == curval:
@@ -71,10 +73,10 @@ def set_opt(cfg, s, o, dflt):
 
 def bool_query(prompt, dflt):
     while True:
-        i = raw_input('%s [%s] ' % (prompt, 'y' if dflt else 'n')).lower()
+        i = input('%s [%s] ' % (prompt, 'y' if dflt else 'n')).lower()
         if not i or i[0] in ('y', 'n'):
             break
-        print 'Enter y or n.'
+        print('Enter y or n.')
     return (not i and dflt) or (i and i[0] == 'y')
 
 
@@ -83,10 +85,10 @@ def edit_sect(cfg, sect, opts):
     if bool_query('Edit section %s?' % sect, False):
         if not cfg.has_section(sect):
             cfg.add_section(sect)
-        print '%s settings:' % sect
+        print('%s settings:' % sect)
         for opt, dflt in opts:
             changed_vals |= set_opt(cfg, sect, opt, dflt)
-        print
+        print()
     else:
         if cfg.has_section(sect) and bool_query('Delete section %s?' % sect,
                                                 False):
@@ -99,12 +101,12 @@ def main():
     try:
         host = sys.argv[1]
     except IndexError:
-        print USAGE % sys.argv[0]
+        print(USAGE % sys.argv[0])
         sys.exit(1)
     try:
         d = DroidSUT(host, retryLimit=1)
-    except DMError, e:
-        print e
+    except DMError as e:
+        print(e)
         sys.exit(1)
     # check if using Negatus and change path accordingly
     ini_path = INI_PATH_JAVA
@@ -112,14 +114,14 @@ def main():
         ini_path = INI_PATH_NEGATUS
     cfg = get_cfg(d, ini_path)
     if not cfg.sections():
-        print 'Empty or missing ini file.'
+        print('Empty or missing ini file.')
     changed_vals = False
-    for sect, opts in SCHEMA.iteritems():
+    for sect, opts in SCHEMA.items():
         changed_vals |= edit_sect(cfg, sect, opts)
     if changed_vals:
         put_cfg(d, cfg, ini_path)
     else:
-        print 'No changes.'
+        print('No changes.')
 
 
 if __name__ == '__main__':
diff --git a/testing/mozbase/mozdevice/sut_tests/dmunit.py b/testing/mozbase/mozdevice/sut_tests/dmunit.py
index b4a3d0b9ba..94cb17b3f1 100644
--- a/testing/mozbase/mozdevice/sut_tests/dmunit.py
+++ b/testing/mozbase/mozdevice/sut_tests/dmunit.py
@@ -48,7 +48,7 @@ class DeviceManagerTestLoader(unittest.TestLoader):
         module = __import__(module_name)
         for name in dir(module):
             obj = getattr(module, name)
-            if (isinstance(obj, (type, types.ClassType)) and
+            if (isinstance(obj, (type, type)) and
                     issubclass(obj, unittest.TestCase)) and \
                     (not self.isTestDevice or obj.runs_on_test_device):
                 tests.append(self.loadTestsFromTestCase(obj))
diff --git a/testing/mozbase/mozdevice/sut_tests/genfiles.py b/testing/mozbase/mozdevice/sut_tests/genfiles.py
index 5ab8d6349e..b4014a600b 100644
--- a/testing/mozbase/mozdevice/sut_tests/genfiles.py
+++ b/testing/mozbase/mozdevice/sut_tests/genfiles.py
@@ -11,7 +11,7 @@ import shutil
 
 def gen_binary_file(path, size):
     with open(path, 'wb') as f:
-        for i in xrange(size):
+        for i in range(size):
             byte = '%c' % randint(0, 255)
             f.write(byte)
 
diff --git a/testing/mozbase/mozdevice/sut_tests/runtests.py b/testing/mozbase/mozdevice/sut_tests/runtests.py
index fffc306e3e..b03be7d6d7 100644
--- a/testing/mozbase/mozdevice/sut_tests/runtests.py
+++ b/testing/mozbase/mozdevice/sut_tests/runtests.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 from optparse import OptionParser
 import logging
 import os
@@ -27,11 +28,11 @@ def main(ip, port, heartbeat_port, scripts, directory, isTestDevice, verbose):
     if scripts:
         # Ensure the user didn't include the .py on the name of the test file
         # (and get rid of it if they did)
-        scripts = map(lambda x: x.split('.')[0], scripts)
+        scripts = [x.split('.')[0] for x in scripts]
     else:
         # Go through the directory and pick up everything
         # named test_*.py and run it
-        testfile = re.compile('^test_.*\.py$')
+        testfile = re.compile(r'^test_.*\.py$')
         files = os.listdir(directory)
 
         for f in files:
@@ -56,7 +57,7 @@ if __name__ == "__main__":
         try:
             env_port = int(env_port)
         except ValueError:
-            print >> sys.stderr, "Port in TEST_DEVICE should be an integer."
+            print("Port in TEST_DEVICE should be an integer.", file=sys.stderr)
             sys.exit(1)
 
     # Deal with the options
diff --git a/testing/mozbase/mozdevice/sut_tests/test_datachannel.py b/testing/mozbase/mozdevice/sut_tests/test_datachannel.py
index 99b71a584d..680ec45dfb 100644
--- a/testing/mozbase/mozdevice/sut_tests/test_datachannel.py
+++ b/testing/mozbase/mozdevice/sut_tests/test_datachannel.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import re
 import socket
 from time import strptime
@@ -30,7 +31,7 @@ class DataChannelTestCase(DeviceManagerTestCase):
         capturedHeader = False
         while numbeats < 3:
             data = self._datasock.recv(1024)
-            print data
+            print(data)
             self.assertNotEqual(len(data), 0)
 
             # Check for the header
diff --git a/testing/mozbase/mozdevice/sut_tests/test_getdir.py b/testing/mozbase/mozdevice/sut_tests/test_getdir.py
index 00ea8c9ae3..66a0694af7 100644
--- a/testing/mozbase/mozdevice/sut_tests/test_getdir.py
+++ b/testing/mozbase/mozdevice/sut_tests/test_getdir.py
@@ -18,7 +18,7 @@ class GetDirectoryTestCase(DeviceManagerTestCase):
         os.makedirs(os.path.join(self.localsrcdir, 'push1', 'sub.1', 'sub.2'))
         path = os.path.join(self.localsrcdir,
                             'push1', 'sub.1', 'sub.2', 'testfile')
-        file(path, 'w').close()
+        open(path, 'w').close()
         os.makedirs(os.path.join(self.localsrcdir, 'push1', 'emptysub'))
         self.localdestdir = tempfile.mkdtemp()
         self.expected_filelist = ['emptysub', 'sub.1']
diff --git a/testing/mozbase/mozdevice/sut_tests/test_info.py b/testing/mozbase/mozdevice/sut_tests/test_info.py
index 57bb4fce01..54a96e65b0 100644
--- a/testing/mozbase/mozdevice/sut_tests/test_info.py
+++ b/testing/mozbase/mozdevice/sut_tests/test_info.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 from dmunit import DeviceManagerTestCase
 
 
@@ -15,6 +16,6 @@ class InfoTestCase(DeviceManagerTestCase):
         cmds = ('os', 'id', 'systime', 'uptime', 'screen', 'memory', 'power')
         for c in cmds:
             data = self.dm.getInfo(c)
-            print c + str(data)
+            print(c + str(data))
 
         # No real good way to verify this.  If it doesn't throw, we're ok.
diff --git a/testing/mozbase/mozdevice/sut_tests/test_prompt.py b/testing/mozbase/mozdevice/sut_tests/test_prompt.py
index 9980ee2ab9..dde349fc68 100644
--- a/testing/mozbase/mozdevice/sut_tests/test_prompt.py
+++ b/testing/mozbase/mozdevice/sut_tests/test_prompt.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import re
 import socket
 
@@ -21,10 +22,10 @@ class PromptTestCase(DeviceManagerTestCase):
         ip = self.dm.host
         port = self.dm.port
 
-        promptre = re.compile('.*\$\>\x00')
+        promptre = re.compile('.*\\$\\>\x00')
         data = ""
         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         self.sock.connect((ip, int(port)))
         data = self.sock.recv(1024)
-        print data
+        print(data)
         self.assertTrue(promptre.match(data))
diff --git a/testing/mozbase/mozdevice/sut_tests/test_pull.py b/testing/mozbase/mozdevice/sut_tests/test_pull.py
index 753d8ddd53..81e4dd4d86 100644
--- a/testing/mozbase/mozdevice/sut_tests/test_pull.py
+++ b/testing/mozbase/mozdevice/sut_tests/test_pull.py
@@ -18,7 +18,7 @@ class PullTestCase(DeviceManagerTestCase):
         orig = hashlib.md5()
         new = hashlib.md5()
         local_test_file = os.path.join('test-files', 'mybinary.zip')
-        orig.update(file(local_test_file, 'r').read())
+        orig.update(open(local_test_file, 'r').read())
 
         testroot = self.dm.deviceRoot
         remote_test_file = posixpath.join(testroot, 'mybinary.zip')
diff --git a/testing/mozbase/mozdevice/sut_tests/test_push1.py b/testing/mozbase/mozdevice/sut_tests/test_push1.py
index f457d6cc55..8859ad9496 100644
--- a/testing/mozbase/mozdevice/sut_tests/test_push1.py
+++ b/testing/mozbase/mozdevice/sut_tests/test_push1.py
@@ -28,7 +28,7 @@ class Push1TestCase(DeviceManagerTestCase):
         if not os.path.exists(p1):
             os.makedirs(os.path.join(p1, 'sub.1', 'sub.2'))
         if not os.path.exists(os.path.join(p1, 'sub.1', 'sub.2', 'testfile')):
-            file(os.path.join(p1, 'sub.1', 'sub.2', 'testfile'), 'w').close()
+            open(os.path.join(p1, 'sub.1', 'sub.2', 'testfile'), 'w').close()
 
         self.dm.pushDir(p1, posixpath.join(dvpath, 'push1'))
 
diff --git a/testing/mozbase/mozdevice/tests/sut.py b/testing/mozbase/mozdevice/tests/sut.py
index 76a5ed3136..dd8f37ea80 100644
--- a/testing/mozbase/mozdevice/tests/sut.py
+++ b/testing/mozbase/mozdevice/tests/sut.py
@@ -10,7 +10,7 @@ import time
 from threading import Thread
 
 
-class MockAgent(object):
+class MockAgent:
 
     MAX_WAIT_TIME_SECONDS = 10
     SOCKET_TIMEOUT_SECONDS = 5
diff --git a/testing/mozbase/mozdevice/tests/sut_copytree.py b/testing/mozbase/mozdevice/tests/sut_copytree.py
index ec22828d07..75a15df0a7 100644
--- a/testing/mozbase/mozdevice/tests/sut_copytree.py
+++ b/testing/mozbase/mozdevice/tests/sut_copytree.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
diff --git a/testing/mozbase/mozdevice/tests/sut_fileMethods.py b/testing/mozbase/mozdevice/tests/sut_fileMethods.py
index 142950a816..7ec69302f4 100644
--- a/testing/mozbase/mozdevice/tests/sut_fileMethods.py
+++ b/testing/mozbase/mozdevice/tests/sut_fileMethods.py
@@ -40,7 +40,7 @@ class TestFileMethods(unittest.TestCase):
     def test_getFile(self):
 
         fname = "/mnt/sdcard/file"
-        commands = [("pull %s" % fname, "%s,%s\n%s" % (fname, len(self.content), self.content)),
+        commands = [("pull %s" % fname, "{},{}\n{}".format(fname, len(self.content), self.content)),
                     ("hash %s" % fname, self.temp_hash)]
 
         with tempfile.NamedTemporaryFile() as f:
@@ -57,7 +57,7 @@ class TestFileMethods(unittest.TestCase):
                     ("cd /mnt/sdcard", ""),
                     ("ls", "file"),
                     ("isdir %s" % fname, "FALSE"),
-                    ("pull %s" % fname, "%s,%s\n%s" % (fname, len(self.content), self.content)),
+                    ("pull %s" % fname, "{},{}\n{}".format(fname, len(self.content), self.content)),
                     ("hash %s" % fname, self.temp_hash)]
 
         tmpdir = tempfile.mkdtemp()
diff --git a/testing/mozbase/mozdevice/tests/sut_info.py b/testing/mozbase/mozdevice/tests/sut_info.py
index 93f3d42581..565dd3dc8a 100644
--- a/testing/mozbase/mozdevice/tests/sut_info.py
+++ b/testing/mozbase/mozdevice/tests/sut_info.py
@@ -40,7 +40,7 @@ class TestGetInfo(unittest.TestCase):
 
             expected = re.sub(r'\ +', ' ', self.commands[directive][1]).split('\n')
             # Account for slightly different return format for 'process'
-            if directive is 'process':
+            if directive == 'process':
                 expected = [[x] for x in expected]
 
             self.assertEqual(d.getInfo(directive=directive)[directive], expected)
diff --git a/testing/mozbase/mozdevice/tests/sut_movetree.py b/testing/mozbase/mozdevice/tests/sut_movetree.py
index 0e106577c8..a674391586 100644
--- a/testing/mozbase/mozdevice/tests/sut_movetree.py
+++ b/testing/mozbase/mozdevice/tests/sut_movetree.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
diff --git a/testing/mozbase/mozdevice/tests/sut_pull.py b/testing/mozbase/mozdevice/tests/sut_pull.py
index c9fcae42a6..8fd12f9fb5 100644
--- a/testing/mozbase/mozdevice/tests/sut_pull.py
+++ b/testing/mozbase/mozdevice/tests/sut_pull.py
@@ -15,7 +15,7 @@ class PullTest(unittest.TestCase):
             # pull file is kind of gross, make sure we can still execute commands after it's done
             remoteName = "/mnt/sdcard/cheeseburgers"
             a = MockAgent(self, commands=[("pull %s" % remoteName,
-                                           "%s,%s\n%s" % (remoteName,
+                                           "{},{}\n{}".format(remoteName,
                                                           len(cheeseburgers),
                                                           cheeseburgers)),
                                           ("isdir /mnt/sdcard", "TRUE")])
@@ -32,7 +32,7 @@ class PullTest(unittest.TestCase):
         # to be larger file
         remoteName = "/mnt/sdcard/cheeseburgers"
         a = MockAgent(self, commands=[("pull %s" % remoteName,
-                                       "%s,15\n%s" % (remoteName,
+                                       "{},15\n{}".format(remoteName,
                                                       "cheeseburgh"))])
         d = mozdevice.DroidSUT("127.0.0.1", port=a.port,
                                logLevel=logging.DEBUG)
diff --git a/testing/mozbase/mozdevice/tests/sut_push.py b/testing/mozbase/mozdevice/tests/sut_push.py
index 023d5315cc..c906c9632d 100644
--- a/testing/mozbase/mozdevice/tests/sut_push.py
+++ b/testing/mozbase/mozdevice/tests/sut_push.py
@@ -18,7 +18,7 @@ class PushTest(unittest.TestCase):
 
         # (good response, no exception), (bad response, exception)
         for response in [(expectedResponse, False), ("BADHASH", True)]:
-            cmd = "push /mnt/sdcard/foobar %s\r\n%s" % (len(pushfile), pushfile)
+            cmd = "push /mnt/sdcard/foobar {}\r\n{}".format(len(pushfile), pushfile)
             a = MockAgent(self, commands=[("isdir /mnt/sdcard", "TRUE"),
                                           (cmd, response[0])])
             exceptionThrown = False
diff --git a/testing/mozbase/mozfile/mozfile/__init__.py b/testing/mozbase/mozfile/mozfile/__init__.py
index a527f0ad6d..011371a64b 100644
--- a/testing/mozbase/mozfile/mozfile/__init__.py
+++ b/testing/mozbase/mozfile/mozfile/__init__.py
@@ -3,6 +3,5 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 from .mozfile import *
diff --git a/testing/mozbase/mozfile/mozfile/mozfile.py b/testing/mozbase/mozfile/mozfile/mozfile.py
index 94805594ec..d9ed7b828b 100644
--- a/testing/mozbase/mozfile/mozfile/mozfile.py
+++ b/testing/mozbase/mozfile/mozfile/mozfile.py
@@ -1,13 +1,11 @@
-# -*- coding: utf-8 -*-
-
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # We don't import all modules at the top for performance reasons. See Bug 1008943
 
-from __future__ import absolute_import
 
+from __future__ import print_function
 from contextlib import contextmanager
 import errno
 import os
@@ -55,7 +53,7 @@ def extract_zip(src, dest):
         try:
             bundle = zipfile.ZipFile(src)
         except Exception:
-            print "src: %s" % src
+            print("src: %s" % src)
             raise
 
     namelist = bundle.namelist()
@@ -161,8 +159,8 @@ def _call_windows_retry(func, args=(), retry_max=5, retry_delay=0.5):
 
             retry_count += 1
 
-            print '%s() failed for "%s". Reason: %s (%s). Retrying...' % \
-                (func.__name__, args, e.strerror, e.errno)
+            print('%s() failed for "%s". Reason: %s (%s). Retrying...' % \
+                (func.__name__, args, e.strerror, e.errno))
             time.sleep(retry_count * retry_delay)
         else:
             # If no exception has been thrown it should be done
@@ -420,9 +418,9 @@ def is_url(thing):
     Return True if thing looks like a URL.
     """
 
-    import urlparse
+    import urllib.parse
 
-    parsed = urlparse.urlparse(thing)
+    parsed = urllib.parse.urlparse(thing)
     if 'scheme' in parsed:
         return len(parsed.scheme) >= 2
     else:
@@ -436,7 +434,7 @@ def load(resource):
     result of urllib2.urlopen()
     """
 
-    import urllib2
+    import urllib.request, urllib.error, urllib.parse
 
     # handle file URLs separately due to python stdlib limitations
     if resource.startswith('file://'):
@@ -444,6 +442,6 @@ def load(resource):
 
     if not is_url(resource):
         # if no scheme is given, it is a file path
-        return file(resource)
+        return open(resource)
 
-    return urllib2.urlopen(resource)
+    return six.moves.urllib.request.urlopen(resource)
diff --git a/testing/mozbase/mozfile/tests/stubs.py b/testing/mozbase/mozfile/tests/stubs.py
index 06d79e7af1..6d7e2ec263 100644
--- a/testing/mozbase/mozfile/tests/stubs.py
+++ b/testing/mozbase/mozfile/tests/stubs.py
@@ -25,7 +25,7 @@ def create_stub():
             if not os.path.exists(dirname):
                 os.makedirs(dirname)
             contents = path[-1]
-            f = file(fullpath, 'w')
+            f = open(fullpath, 'w')
             f.write(contents)
             f.close()
         return tempdir
diff --git a/testing/mozbase/mozfile/tests/test_extract.py b/testing/mozbase/mozfile/tests/test_extract.py
index e91f52349b..71a53b8cb3 100644
--- a/testing/mozbase/mozfile/tests/test_extract.py
+++ b/testing/mozbase/mozfile/tests/test_extract.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+from __future__ import print_function
 import os
 import shutil
 import tarfile
@@ -21,10 +22,10 @@ class TestExtract(unittest.TestCase):
             path = os.path.join(directory, *f)
             exists = os.path.exists(path)
             if not exists:
-                print "%s does not exist" % (os.path.join(f))
+                print("%s does not exist" % (os.path.join(f)))
             self.assertTrue(exists)
             if exists:
-                contents = file(path).read().strip()
+                contents = open(path).read().strip()
                 self.assertTrue(contents == f[-1])
 
     def test_extract_zipfile(self):
diff --git a/testing/mozbase/mozfile/tests/test_load.py b/testing/mozbase/mozfile/tests/test_load.py
index 13a5b519c1..f6630fc6ec 100755
--- a/testing/mozbase/mozfile/tests/test_load.py
+++ b/testing/mozbase/mozfile/tests/test_load.py
@@ -45,7 +45,7 @@ class TestLoad(unittest.TestCase):
             tmp.close()
 
             # read the file
-            contents = file(tmp.name).read()
+            contents = open(tmp.name).read()
             self.assertEqual(contents, 'foo bar')
 
             # read the file with load and a file path
diff --git a/testing/mozbase/mozfile/tests/test_move_remove.py b/testing/mozbase/mozfile/tests/test_move_remove.py
index e9d0cd4347..72cd444a33 100644
--- a/testing/mozbase/mozfile/tests/test_move_remove.py
+++ b/testing/mozbase/mozfile/tests/test_move_remove.py
@@ -77,7 +77,7 @@ class MozfileRemoveTestCase(unittest.TestCase):
         """Test removing a directory with an open file"""
         # Open a file in the generated stub
         filepath = os.path.join(self.tempdir, *stubs.files[1])
-        f = file(filepath, 'w')
+        f = open(filepath, 'w')
         f.write('foo-bar')
 
         # keep file open and then try removing the dir-tree
diff --git a/testing/mozbase/mozfile/tests/test_tempfile.py b/testing/mozbase/mozfile/tests/test_tempfile.py
index 3c3d26d5d6..c395e484ac 100644
--- a/testing/mozbase/mozfile/tests/test_tempfile.py
+++ b/testing/mozbase/mozfile/tests/test_tempfile.py
@@ -66,7 +66,7 @@ class TestNamedTemporaryFile(unittest.TestCase):
         path = None
         with mozfile.NamedTemporaryFile(delete=True) as tf:
             path = tf.name
-        self.assertTrue(isinstance(path, basestring))
+        self.assertTrue(isinstance(path, str))
         self.assertFalse(os.path.exists(path))
 
         # it is also deleted when __del__ is called
diff --git a/testing/mozbase/mozhttpd/mozhttpd/__init__.py b/testing/mozbase/mozhttpd/mozhttpd/__init__.py
index c15b0d0285..1575bd59f2 100644
--- a/testing/mozbase/mozhttpd/mozhttpd/__init__.py
+++ b/testing/mozbase/mozhttpd/mozhttpd/__init__.py
@@ -37,12 +37,12 @@ content from the current directory, defines a single API endpoint
                             urlhandlers = [ { 'method': 'GET',
                                               'path': '/api/resources/([^/]+)/?',
                                               'function': resource_get } ])
-  print "Serving '%s' at %s:%s" % (httpd.docroot, httpd.host, httpd.port)
+  print("Serving '%s' at %s:%s" % (httpd.docroot, httpd.host, httpd.port))
   httpd.start(block=True)
 
 """
 
-from mozhttpd import MozHttpd, Request, RequestHandler, main
-from handlers import json_response
+from .mozhttpd import MozHttpd, Request, RequestHandler, main
+from .handlers import json_response
 
 __all__ = ['MozHttpd', 'Request', 'RequestHandler', 'main', 'json_response']
diff --git a/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py b/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py
index 4ca0847d2a..dfd2a6a435 100755
--- a/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py
+++ b/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py
@@ -4,8 +4,9 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import BaseHTTPServer
-import SimpleHTTPServer
+from __future__ import print_function
+import http.server as BaseHTTPServer
+import http.server as SimpleHTTPServer
 import errno
 import logging
 import threading
@@ -13,12 +14,13 @@ import posixpath
 import socket
 import sys
 import os
-import urllib
-import urlparse
+import urllib.request
+import urllib.parse
+import urllib.error
 import re
 import moznetwork
 import time
-from SocketServer import ThreadingMixIn
+from socketserver import ThreadingMixIn
 
 
 class EasyServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
@@ -26,7 +28,7 @@ class EasyServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
     acceptable_errors = (errno.EPIPE, errno.ECONNABORTED)
 
     def handle_error(self, request, client_address):
-        error = sys.exc_value
+        error = sys.exc_info()[1]
 
         if ((isinstance(error, socket.error) and
              isinstance(error.args, tuple) and
@@ -48,7 +50,7 @@ class Request(object):
     def __init__(self, uri, headers, rfile=None):
         self.uri = uri
         self.headers = headers
-        parsed = urlparse.urlsplit(uri)
+        parsed = urllib.parse.urlsplit(uri)
         for i, attr in enumerate(self.uri_attrs):
             setattr(self, attr, parsed[i])
         try:
@@ -87,7 +89,7 @@ class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
                 (response_code, headerdict, data) = \
                     handler['function'](self.request, *m.groups())
                 self.send_response(response_code)
-                for (keyword, value) in headerdict.iteritems():
+                for (keyword, value) in headerdict.items():
                     self.send_header(keyword, value)
                 self.end_headers()
                 self.wfile.write(data)
@@ -100,9 +102,9 @@ class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         """Find the on-disk path to serve this request from,
         using self.path_mappings and self.docroot.
         Return (url_path, disk_path)."""
-        path_components = filter(None, self.request.path.split('/'))
-        for prefix, disk_path in self.path_mappings.iteritems():
-            prefix_components = filter(None, prefix.split('/'))
+        path_components = [_f for _f in self.request.path.split('/') if _f]
+        for prefix, disk_path in self.path_mappings.items():
+            prefix_components = [_f for _f in prefix.split('/') if _f]
             if len(path_components) < len(prefix_components):
                 continue
             if path_components[:len(prefix_components)] == prefix_components:
@@ -156,9 +158,9 @@ class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         # except we serve from self.docroot instead of os.getcwd(), and
         # parse_request()/do_GET() have already stripped the query string and
         # fragment and mangled the path for proxying, if required.
-        path = posixpath.normpath(urllib.unquote(self.path))
+        path = posixpath.normpath(urllib.parse.unquote(self.path))
         words = path.split('/')
-        words = filter(None, words)
+        words = [_f for _f in words if _f]
         path = self.disk_root
         for word in words:
             drive, word = os.path.splitdrive(word)
@@ -323,7 +325,7 @@ def main(args=sys.argv[1:]):
     # create the server
     server = MozHttpd(host=host, port=options.port, docroot=options.docroot)
 
-    print "Serving '%s' at %s:%s" % (server.docroot, server.host, server.port)
+    print(("Serving '%s' at %s:%s" % (server.docroot, server.host, server.port)))
     server.start(block=True)
 
 if __name__ == '__main__':
diff --git a/testing/mozbase/mozhttpd/tests/api.py b/testing/mozbase/mozhttpd/tests/api.py
index b785ac5ef7..82a03a46b5 100644
--- a/testing/mozbase/mozhttpd/tests/api.py
+++ b/testing/mozbase/mozhttpd/tests/api.py
@@ -6,7 +6,7 @@
 
 import mozfile
 import mozhttpd
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import os
 import unittest
 import json
@@ -42,7 +42,7 @@ class ApiTest(unittest.TestCase):
                       'query': request.query})
 
     def get_url(self, path, server_port, querystr):
-        url = "http://127.0.0.1:%s%s" % (server_port, path)
+        url = "http://127.0.0.1:{}{}".format(server_port, path)
         if querystr:
             url += "?%s" % querystr
         return url
@@ -50,7 +50,7 @@ class ApiTest(unittest.TestCase):
     def try_get(self, server_port, querystr):
         self.resource_get_called = 0
 
-        f = urllib2.urlopen(self.get_url('/api/resource/1', server_port, querystr))
+        f = six.moves.urllib.request.urlopen(self.get_url('/api/resource/1', server_port, querystr))
         try:
             self.assertEqual(f.getcode(), 200)
         except AttributeError:
@@ -63,9 +63,9 @@ class ApiTest(unittest.TestCase):
 
         postdata = {'hamburgers': '1234'}
         try:
-            f = urllib2.urlopen(self.get_url('/api/resource/', server_port, querystr),
+            f = six.moves.urllib.request.urlopen(self.get_url('/api/resource/', server_port, querystr),
                                 data=json.dumps(postdata))
-        except urllib2.HTTPError as e:
+        except six.moves.urllib.error.HTTPError as e:
             # python 2.4
             self.assertEqual(e.code, 201)
             body = e.fp.read()
@@ -80,8 +80,8 @@ class ApiTest(unittest.TestCase):
     def try_del(self, server_port, querystr):
         self.resource_del_called = 0
 
-        opener = urllib2.build_opener(urllib2.HTTPHandler)
-        request = urllib2.Request(self.get_url('/api/resource/1', server_port, querystr))
+        opener = six.moves.urllib.request.build_opener(six.moves.urllib.request.HTTPHandler)
+        request = six.moves.urllib.request.Request(self.get_url('/api/resource/1', server_port, querystr))
         request.get_method = lambda: 'DEL'
         f = opener.open(request)
 
@@ -123,8 +123,8 @@ class ApiTest(unittest.TestCase):
         # GET: By default we don't serve any files if we just define an API
         exception_thrown = False
         try:
-            urllib2.urlopen(self.get_url('/', server_port, None))
-        except urllib2.HTTPError as e:
+            six.moves.urllib.request.urlopen(self.get_url('/', server_port, None))
+        except six.moves.urllib.error.HTTPError as e:
             self.assertEqual(e.code, 404)
             exception_thrown = True
         self.assertTrue(exception_thrown)
@@ -139,8 +139,8 @@ class ApiTest(unittest.TestCase):
         # GET: Return 404 for non-existent endpoint
         exception_thrown = False
         try:
-            urllib2.urlopen(self.get_url('/api/resource/', server_port, None))
-        except urllib2.HTTPError as e:
+            six.moves.urllib.request.urlopen(self.get_url('/api/resource/', server_port, None))
+        except six.moves.urllib.error.HTTPError as e:
             self.assertEqual(e.code, 404)
             exception_thrown = True
         self.assertTrue(exception_thrown)
@@ -148,9 +148,9 @@ class ApiTest(unittest.TestCase):
         # POST: POST should also return 404
         exception_thrown = False
         try:
-            urllib2.urlopen(self.get_url('/api/resource/', server_port, None),
+            six.moves.urllib.request.urlopen(self.get_url('/api/resource/', server_port, None),
                             data=json.dumps({}))
-        except urllib2.HTTPError as e:
+        except six.moves.urllib.error.HTTPError as e:
             self.assertEqual(e.code, 404)
             exception_thrown = True
         self.assertTrue(exception_thrown)
@@ -158,12 +158,12 @@ class ApiTest(unittest.TestCase):
         # DEL: DEL should also return 404
         exception_thrown = False
         try:
-            opener = urllib2.build_opener(urllib2.HTTPHandler)
-            request = urllib2.Request(self.get_url('/api/resource/', server_port,
+            opener = six.moves.urllib.request.build_opener(six.moves.urllib.request.HTTPHandler)
+            request = six.moves.urllib.request.Request(self.get_url('/api/resource/', server_port,
                                                    None))
             request.get_method = lambda: 'DEL'
             opener.open(request)
-        except urllib2.HTTPError:
+        except six.moves.urllib.error.HTTPError:
             self.assertEqual(e.code, 404)
             exception_thrown = True
         self.assertTrue(exception_thrown)
@@ -177,7 +177,7 @@ class ApiTest(unittest.TestCase):
         server_port = httpd.httpd.server_port
 
         # We defined a docroot, so we expect a directory listing
-        f = urllib2.urlopen(self.get_url('/', server_port, None))
+        f = six.moves.urllib.request.urlopen(self.get_url('/', server_port, None))
         try:
             self.assertEqual(f.getcode(), 200)
         except AttributeError:
@@ -193,7 +193,7 @@ class ProxyTest(unittest.TestCase):
 
     def tearDown(self):
         # reset proxy opener in case it changed
-        urllib2.install_opener(None)
+        six.moves.urllib.request.install_opener(None)
 
     def test_proxy(self):
         docroot = tempfile.mkdtemp()
@@ -207,7 +207,7 @@ class ProxyTest(unittest.TestCase):
 
         def index_contents(host): return '%s index' % host
 
-        index = file(os.path.join(docroot, index_filename), 'w')
+        index = open(os.path.join(docroot, index_filename), 'w')
         index.write(index_contents('*'))
         index.close()
 
@@ -215,12 +215,12 @@ class ProxyTest(unittest.TestCase):
         httpd.start(block=False)
         server_port = httpd.httpd.server_port
 
-        proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:%d' %
+        proxy_support = six.moves.urllib.request.ProxyHandler({'http': 'http://127.0.0.1:%d' %
                                               server_port})
-        urllib2.install_opener(urllib2.build_opener(proxy_support))
+        six.moves.urllib.request.install_opener(six.moves.urllib.request.build_opener(proxy_support))
 
         for host in hosts:
-            f = urllib2.urlopen(url(host))
+            f = six.moves.urllib.request.urlopen(url(host))
             try:
                 self.assertEqual(f.getcode(), 200)
             except AttributeError:
@@ -235,18 +235,18 @@ class ProxyTest(unittest.TestCase):
         httpd.start(block=False)
         server_port = httpd.httpd.server_port
 
-        proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:%d' %
+        proxy_support = six.moves.urllib.request.ProxyHandler({'http': 'http://127.0.0.1:%d' %
                                               server_port})
-        urllib2.install_opener(urllib2.build_opener(proxy_support))
+        six.moves.urllib.request.install_opener(six.moves.urllib.request.build_opener(proxy_support))
 
         # set up dirs
         for host in hosts:
             os.mkdir(os.path.join(docroot, host))
-            file(os.path.join(docroot, host, index_filename), 'w') \
+            open(os.path.join(docroot, host, index_filename), 'w') \
                 .write(index_contents(host))
 
         for host in hosts:
-            f = urllib2.urlopen(url(host))
+            f = six.moves.urllib.request.urlopen(url(host))
             try:
                 self.assertEqual(f.getcode(), 200)
             except AttributeError:
@@ -255,8 +255,8 @@ class ProxyTest(unittest.TestCase):
 
         exc = None
         try:
-            urllib2.urlopen(url(unproxied_host))
-        except urllib2.HTTPError as e:
+            six.moves.urllib.request.urlopen(url(unproxied_host))
+        except six.moves.urllib.error.HTTPError as e:
             exc = e
         self.assertNotEqual(exc, None)
         self.assertEqual(exc.code, 404)
diff --git a/testing/mozbase/mozhttpd/tests/filelisting.py b/testing/mozbase/mozhttpd/tests/filelisting.py
index 6abea757f2..75b59a70cf 100644
--- a/testing/mozbase/mozhttpd/tests/filelisting.py
+++ b/testing/mozbase/mozhttpd/tests/filelisting.py
@@ -5,7 +5,7 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import mozhttpd
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import os
 import unittest
 import re
@@ -20,9 +20,9 @@ class FileListingTest(unittest.TestCase):
 
         httpd = mozhttpd.MozHttpd(port=0, docroot=here)
         httpd.start(block=False)
-        f = urllib2.urlopen("http://%s:%s/%s" % ('127.0.0.1', httpd.httpd.server_port, path))
+        f = six.moves.urllib.request.urlopen("http://{}:{}/{}".format('127.0.0.1', httpd.httpd.server_port, path))
         for line in f.readlines():
-            webline = re.sub('\<[a-zA-Z0-9\-\_\.\=\"\'\/\\\%\!\@\#\$\^\&\*\(\) ]*\>',
+            webline = re.sub('\\<[a-zA-Z0-9\\-\\_\\.\\=\"\'\\/\\\\%\\!\\@\\#\\$\\^\\&\\*\\(\\) ]*\\>',
                              '', line.strip('\n')).strip('/').strip().strip('@')
 
             if webline and not webline.startswith("Directory listing for"):
diff --git a/testing/mozbase/mozhttpd/tests/paths.py b/testing/mozbase/mozhttpd/tests/paths.py
index 45ae40144d..e6bde9f3ee 100644
--- a/testing/mozbase/mozhttpd/tests/paths.py
+++ b/testing/mozbase/mozhttpd/tests/paths.py
@@ -7,19 +7,19 @@ from mozfile import TemporaryDirectory
 import mozhttpd
 import os
 import unittest
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 
 
 class PathTest(unittest.TestCase):
 
     def try_get(self, url, expected_contents):
-        f = urllib2.urlopen(url)
+        f = six.moves.urllib.request.urlopen(url)
         self.assertEqual(f.getcode(), 200)
         self.assertEqual(f.read(), expected_contents)
 
     def try_get_expect_404(self, url):
-        with self.assertRaises(urllib2.HTTPError) as cm:
-            urllib2.urlopen(url)
+        with self.assertRaises(six.moves.urllib.error.HTTPError) as cm:
+            six.moves.urllib.request.urlopen(url)
         self.assertEqual(404, cm.exception.code)
 
     def test_basic(self):
diff --git a/testing/mozbase/mozhttpd/tests/requestlog.py b/testing/mozbase/mozhttpd/tests/requestlog.py
index bf2c59ec3f..2ee0772113 100644
--- a/testing/mozbase/mozhttpd/tests/requestlog.py
+++ b/testing/mozbase/mozhttpd/tests/requestlog.py
@@ -3,7 +3,7 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import mozhttpd
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import os
 import unittest
 
@@ -16,8 +16,8 @@ class RequestLogTest(unittest.TestCase):
 
         httpd = mozhttpd.MozHttpd(port=0, docroot=here, log_requests=log_requests)
         httpd.start(block=False)
-        url = "http://%s:%s/" % ('127.0.0.1', httpd.httpd.server_port)
-        f = urllib2.urlopen(url)
+        url = "http://{}:{}/".format('127.0.0.1', httpd.httpd.server_port)
+        f = six.moves.urllib.request.urlopen(url)
         f.read()
 
         return httpd.request_log
diff --git a/testing/mozbase/mozinfo/mozinfo/__init__.py b/testing/mozbase/mozinfo/mozinfo/__init__.py
index 7d0483cb57..d02f9510e1 100644
--- a/testing/mozbase/mozinfo/mozinfo/__init__.py
+++ b/testing/mozbase/mozinfo/mozinfo/__init__.py
@@ -3,7 +3,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 """
 interface to transform introspected system information to a format palatable to
diff --git a/testing/mozbase/mozinfo/mozinfo/mozinfo.py b/testing/mozbase/mozinfo/mozinfo/mozinfo.py
index 81a30307dd..bd767de198 100755
--- a/testing/mozbase/mozinfo/mozinfo/mozinfo.py
+++ b/testing/mozbase/mozinfo/mozinfo/mozinfo.py
@@ -8,7 +8,6 @@
 # linux) to the information; I certainly wouldn't want anyone parsing this
 # information and having behaviour depend on it
 
-from __future__ import absolute_import
 
 import os
 import platform
@@ -92,10 +91,16 @@ elif system.startswith('MINGW'):
     info['os'] = 'win'
     os_version = version = unknown
 elif system == "Linux":
-    if hasattr(platform, "linux_distribution"):
-        (distro, os_version, codename) = platform.linux_distribution()
-    else:
-        (distro, os_version, codename) = platform.dist()
+    try:
+        import distro as _distro_module
+        distro = _distro_module.name()
+        os_version = _distro_module.version()
+        codename = _distro_module.codename()
+    except ImportError:
+        if hasattr(platform, "linux_distribution"):
+            (distro, os_version, codename) = platform.linux_distribution()
+        else:
+            distro, os_version, codename = '', '', ''
     if not processor:
         processor = machine
     version = "%s %s" % (distro, os_version)
@@ -140,7 +145,7 @@ elif processor.upper() == "AMD64":
     processor = "x86_64"
 elif processor == "Power Macintosh":
     processor = "ppc"
-bits = re.search('(\d+)bit', bits).group(1)
+bits = re.search(r'(\d+)bit', bits).group(1)
 info.update({'processor': processor,
              'bits': int(bits),
              })
@@ -184,7 +189,7 @@ def update(new_info):
                      to a json file containing the new info.
     """
 
-    if isinstance(new_info, basestring):
+    if isinstance(new_info, str):
         # lazy import
         import mozfile
         import json
@@ -246,7 +251,7 @@ def output_to_file(path):
 update({})
 
 # exports
-__all__ = info.keys()
+__all__ = list(info.keys())
 __all__ += ['is' + os_name.title() for os_name in choices['os']]
 __all__ += [
     'info',
@@ -286,15 +291,15 @@ def main(args=None):
     flag = False
     for key, value in options.__dict__.items():
         if value is True:
-            print '%s choices: %s' % (key, ' '.join([str(choice)
-                                                     for choice in choices[key]]))
+            print('%s choices: %s' % (key, ' '.join([str(choice)
+                                                     for choice in choices[key]])))
             flag = True
     if flag:
         return
 
     # otherwise, print out all info
     for key, value in info.items():
-        print '%s: %s' % (key, value)
+        print('%s: %s' % (key, value))
 
 if __name__ == '__main__':
     main()
diff --git a/testing/mozbase/mozinfo/mozinfo/string_version.py b/testing/mozbase/mozinfo/mozinfo/string_version.py
index fd77fa566a..a554677cd4 100644
--- a/testing/mozbase/mozinfo/mozinfo/string_version.py
+++ b/testing/mozbase/mozinfo/mozinfo/string_version.py
@@ -2,16 +2,40 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from distutils.version import LooseVersion
-
-
+try:
+    from distutils.version import LooseVersion
+except ImportError:
+    import re as _re
+    class LooseVersion:
+        def __init__(self, vstring):
+            self.vstring = vstring
+            self.version = [int(x) if x.isdigit() else x for x in _re.split(r'[.\-]', vstring)]
+        def __str__(self): return self.vstring
+        def __repr__(self): return "LooseVersion ('%s')" % str(self)
+        def _cmp(self, other):
+            if not isinstance(other, LooseVersion): other = LooseVersion(other)
+            a, b = self.version, other.version
+            for i in range(max(len(a), len(b))):
+                va = a[i] if i < len(a) else 0
+                vb = b[i] if i < len(b) else 0
+                if type(va) != type(vb): va, vb = str(va), str(vb)
+                if va < vb: return -1
+                if va > vb: return 1
+            return 0
+        def __eq__(self, other): return self._cmp(other) == 0
+        def __lt__(self, other): return self._cmp(other) < 0
+        def __le__(self, other): return self._cmp(other) <= 0
+        def __gt__(self, other): return self._cmp(other) > 0
+        def __ge__(self, other): return self._cmp(other) >= 0
 class StringVersion(str):
     """
     A string version that can be compared with comparison operators.
     """
 
+    def __new__(cls, vstring):
+        return str.__new__(cls, vstring)
+
     def __init__(self, vstring):
-        str.__init__(self, vstring)
         self.version = LooseVersion(vstring)
 
     def __repr__(self):
diff --git a/testing/mozbase/mozinfo/tests/test.py b/testing/mozbase/mozinfo/tests/test.py
index b9457cff9d..af4662c460 100644
--- a/testing/mozbase/mozinfo/tests/test.py
+++ b/testing/mozbase/mozinfo/tests/test.py
@@ -5,7 +5,7 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import json
-import mock
+from unittest import mock
 import os
 import shutil
 import sys
diff --git a/testing/mozbase/mozinstall/mozinstall/__init__.py b/testing/mozbase/mozinstall/mozinstall/__init__.py
index 5f96b7facd..09c6d10a3d 100644
--- a/testing/mozbase/mozinstall/mozinstall/__init__.py
+++ b/testing/mozbase/mozinstall/mozinstall/__init__.py
@@ -3,4 +3,4 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from mozinstall import *
+from .mozinstall import *
diff --git a/testing/mozbase/mozinstall/mozinstall/mozinstall.py b/testing/mozbase/mozinstall/mozinstall/mozinstall.py
index b4c6f95f74..69aead088f 100755
--- a/testing/mozbase/mozinstall/mozinstall/mozinstall.py
+++ b/testing/mozbase/mozinstall/mozinstall/mozinstall.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 from optparse import OptionParser
 import os
 import shutil
@@ -13,6 +14,7 @@ import zipfile
 
 import mozfile
 import mozinfo
+import six
 
 try:
     import pefile
@@ -134,9 +136,9 @@ def install(src, dest):
                     pass
         if issubclass(cls, Exception):
             error = InstallError('Failed to install "%s (%s)"' % (src, str(exc)))
-            raise InstallError, error, trbk
+            six.reraise(InstallError, error, trbk)
         # any other kind of exception like KeyboardInterrupt is just re-raised.
-        raise cls, exc, trbk
+        six.reraise(cls, exc, trbk)
 
     finally:
         # trbk won't get GC'ed due to circular reference
@@ -207,7 +209,7 @@ def uninstall(install_folder):
         if os.path.isfile(log_file):
             trbk = None
             try:
-                cmdArgs = ['%s\uninstall\helper.exe' % install_folder, '/S']
+                cmdArgs = ['%s\uninstall\\helper.exe' % install_folder, '/S']
                 result = subprocess.call(cmdArgs)
                 if result is not 0:
                     raise Exception('Execution of uninstaller failed.')
@@ -222,10 +224,10 @@ def uninstall(install_folder):
                     if time.time() > end_time:
                         raise Exception('Failure removing uninstall folder.')
 
-            except Exception, ex:
+            except Exception as ex:
                 cls, exc, trbk = sys.exc_info()
                 error = UninstallError('Failed to uninstall %s (%s)' % (install_folder, str(ex)))
-                raise UninstallError, error, trbk
+                six.reraise(UninstallError, error, trbk)
 
             finally:
                 # trbk won't get GC'ed due to circular reference
@@ -328,7 +330,7 @@ def install_cli(argv=sys.argv[1:]):
         install_path = install(src, options.dest)
         binary = get_binary(install_path, app_name=options.app)
 
-    print binary
+    print(binary)
 
 
 def uninstall_cli(argv=sys.argv[1:]):
diff --git a/testing/mozbase/mozinstall/setup.py b/testing/mozbase/mozinstall/setup.py
index 7759f0728e..8d5320183e 100644
--- a/testing/mozbase/mozinstall/setup.py
+++ b/testing/mozbase/mozinstall/setup.py
@@ -7,8 +7,8 @@ from setuptools import setup
 
 try:
     here = os.path.dirname(os.path.abspath(__file__))
-    description = file(os.path.join(here, 'README.md')).read()
-except IOError:
+    description = open(os.path.join(here, 'README.md')).read()
+except OSError:
     description = None
 
 PACKAGE_VERSION = '1.12'
diff --git a/testing/mozbase/mozleak/mozleak/leaklog.py b/testing/mozbase/mozleak/mozleak/leaklog.py
index 9688974d1c..ba1980d530 100644
--- a/testing/mozbase/mozleak/mozleak/leaklog.py
+++ b/testing/mozbase/mozleak/mozleak/leaklog.py
@@ -41,7 +41,7 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
     leakedObjectAnalysis = []
     leakedObjectNames = []
     recordLeakedObjects = False
-    with open(leakLogFileName, "r") as leaks:
+    with open(leakLogFileName) as leaks:
         for line in leaks:
             if line.find("purposefully crash") > -1:
                 crashedOnPurpose = True
diff --git a/testing/mozbase/mozlog/mozlog/commandline.py b/testing/mozbase/mozlog/mozlog/commandline.py
index 1077081548..d12d60aabb 100644
--- a/testing/mozbase/mozlog/mozlog/commandline.py
+++ b/testing/mozbase/mozlog/mozlog/commandline.py
@@ -121,7 +121,7 @@ def add_logging_group(parser, include_formatters=None):
                          "or '-' to write to stdout.")
 
     if include_formatters is None:
-        include_formatters = log_formatters.keys()
+        include_formatters = list(log_formatters.keys())
 
     if isinstance(parser, optparse.OptionParser):
         group = optparse.OptionGroup(parser,
@@ -136,16 +136,16 @@ def add_logging_group(parser, include_formatters=None):
         opt_log_type = log_file
         group_add = group.add_argument
 
-    for name, (cls, help_str) in log_formatters.iteritems():
+    for name, (cls, help_str) in log_formatters.items():
         if name in include_formatters:
             group_add("--log-" + name, action="append", type=opt_log_type,
                       help=help_str)
 
-    for optname, (cls, help_str, formatters_, action) in fmt_options.iteritems():
+    for optname, (cls, help_str, formatters_, action) in fmt_options.items():
         for fmt in formatters_:
             # make sure fmt is in log_formatters and is accepted
             if fmt in log_formatters and fmt in include_formatters:
-                group_add("--log-%s-%s" % (fmt, optname), action=action,
+                group_add("--log-{}-{}".format(fmt, optname), action=action,
                           help=help_str, default=None)
 
 
@@ -165,12 +165,12 @@ def setup_handlers(logger, formatters, formatter_options, allow_unused_options=F
                list(unused_options))
         raise ValueError(msg)
 
-    for fmt, streams in formatters.iteritems():
+    for fmt, streams in formatters.items():
         formatter_cls = log_formatters[fmt][0]
         formatter = formatter_cls()
         handler_wrappers_and_options = []
 
-        for option, value in formatter_options[fmt].iteritems():
+        for option, value in formatter_options[fmt].items():
             wrapper, wrapper_args = None, ()
             if option == "valgrind":
                 wrapper = valgrind_handler_wrapper
@@ -232,7 +232,7 @@ def setup_logging(logger, args, defaults=None, formatter_defaults=None,
         else:
             defaults = {"raw": sys.stdout}
 
-    for name, values in args.iteritems():
+    for name, values in args.items():
         parts = name.split('_')
         if len(parts) > 3:
             continue
@@ -246,7 +246,7 @@ def setup_logging(logger, args, defaults=None, formatter_defaults=None,
                 _, formatter = parts
                 for value in values:
                     found = True
-                    if isinstance(value, basestring):
+                    if isinstance(value, str):
                         value = log_file(value)
                     if value == sys.stdout:
                         found_stdout_logger = True
@@ -260,11 +260,11 @@ def setup_logging(logger, args, defaults=None, formatter_defaults=None,
 
     # If there is no user-specified logging, go with the default options
     if not found:
-        for name, value in defaults.iteritems():
+        for name, value in defaults.items():
             formatters[name].append(value)
 
-    elif not found_stdout_logger and sys.stdout in defaults.values():
-        for name, value in defaults.iteritems():
+    elif not found_stdout_logger and sys.stdout in list(defaults.values()):
+        for name, value in defaults.items():
             if value == sys.stdout:
                 formatters[name].append(value)
 
diff --git a/testing/mozbase/mozlog/mozlog/formatters/__init__.py b/testing/mozbase/mozlog/mozlog/formatters/__init__.py
index 5d37ecda81..0ab088a5a8 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/__init__.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/__init__.py
@@ -2,12 +2,12 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from unittest import UnittestFormatter
-from xunit import XUnitFormatter
-from html import HTMLFormatter
-from machformatter import MachFormatter
-from tbplformatter import TbplFormatter
-from errorsummary import ErrorSummaryFormatter
+from .unittest import UnittestFormatter
+from .xunit import XUnitFormatter
+from .html import HTMLFormatter
+from .machformatter import MachFormatter
+from .tbplformatter import TbplFormatter
+from .errorsummary import ErrorSummaryFormatter
 
 try:
     import ujson as json
diff --git a/testing/mozbase/mozlog/mozlog/formatters/errorsummary.py b/testing/mozbase/mozlog/mozlog/formatters/errorsummary.py
index 5e0e844743..5040995fac 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/errorsummary.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/errorsummary.py
@@ -4,7 +4,7 @@
 
 import json
 
-from base import BaseFormatter
+from .base import BaseFormatter
 
 
 class ErrorSummaryFormatter(BaseFormatter):
diff --git a/testing/mozbase/mozlog/mozlog/formatters/html/__init__.py b/testing/mozbase/mozlog/mozlog/formatters/html/__init__.py
index e607ecb87e..0926e46312 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/html/__init__.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/html/__init__.py
@@ -1,3 +1,3 @@
-from html import HTMLFormatter
+from .html import HTMLFormatter
 
 __all__ = ['HTMLFormatter']
diff --git a/testing/mozbase/mozlog/mozlog/formatters/html/html.py b/testing/mozbase/mozlog/mozlog/formatters/html/html.py
index 0ec244aa6a..c176f2672a 100755
--- a/testing/mozbase/mozlog/mozlog/formatters/html/html.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/html/html.py
@@ -4,7 +4,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import base64
-import cgi
+import html as _html_escape_module
 from datetime import datetime
 import os
 
@@ -158,7 +158,7 @@ class HTMLFormatter(base.BaseFormatter):
                     # Encode base64 to avoid that some browsers (such as Firefox, Opera)
                     # treats '#' as the start of another link if it is contained in the data URL.
                     # Use 'charset=utf-8' to show special characters like Chinese.
-                    utf_encoded = unicode(content).encode('utf-8', 'xmlcharrefreplace')
+                    utf_encoded = str(content).encode('utf-8', 'xmlcharrefreplace')
                     href = 'data:text/html;charset=utf-8;base64,%s' % base64.b64encode(utf_encoded)
 
                 links_html.append(html.a(
@@ -177,9 +177,9 @@ class HTMLFormatter(base.BaseFormatter):
                     log.append(line[:80])
                 else:
                     if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
-                        log.append(html.span(raw(cgi.escape(line)), class_='error'))
+                        log.append(html.span(raw(_html_escape_module.escape(line)), class_='error'))
                     else:
-                        log.append(raw(cgi.escape(line)))
+                        log.append(raw(_html_escape_module.escape(line)))
                 log.append(html.br())
             additional_html.append(log)
 
@@ -198,7 +198,7 @@ class HTMLFormatter(base.BaseFormatter):
                 self.head,
                 html.body(
                     html.script(raw(main_f.read())),
-                    html.p('Report generated on %s at %s' % (
+                    html.p('Report generated on {} at {}'.format(
                         generated.strftime('%d-%b-%Y'),
                         generated.strftime('%H:%M:%S'))),
                     html.h2('Environment'),
@@ -208,7 +208,7 @@ class HTMLFormatter(base.BaseFormatter):
                         id='environment'),
 
                     html.h2('Summary'),
-                    html.p('%i tests ran in %.1f seconds.' % (sum(self.test_count.itervalues()),
+                    html.p('%i tests ran in %.1f seconds.' % (sum(self.test_count.values()),
                                                               (self.suite_times["end"] -
                                                                self.suite_times["start"]) / 1000.),
                            html.br(),
@@ -233,4 +233,4 @@ class HTMLFormatter(base.BaseFormatter):
                         html.tbody(self.result_rows,
                                    id='results-table-body')], id='results-table')))
 
-        return u"\n" + doc.unicode(indent=2)
+        return "\n" + doc.str(indent=2)
diff --git a/testing/mozbase/mozlog/mozlog/formatters/html/xmlgen.py b/testing/mozbase/mozlog/mozlog/formatters/html/xmlgen.py
index e5998cda33..e405999c6b 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/html/xmlgen.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/html/xmlgen.py
@@ -24,18 +24,13 @@ by holger krekel, holger at merlinux eu. 2009
 import sys
 import re
 
-if sys.version_info >= (3, 0):
-    def u(s):
-        return s
+def u(s):
+    return s
 
-    def unicode(x):
-        if hasattr(x, '__unicode__'):
-            return x.__unicode__()
-        return str(x)
-else:
-    def u(s):
-        return unicode(s)
-    unicode = unicode
+def str(x):
+    if hasattr(x, '__unicode__'):
+        return x.__unicode__()
+    return str(x)
 
 
 class NamespaceMetaclass(type):
@@ -58,20 +53,20 @@ class NamespaceMetaclass(type):
 
 class Tag(list):
 
-    class Attr(object):
+    class Attr:
 
         def __init__(self, **kwargs):
             self.__dict__.update(kwargs)
 
     def __init__(self, *args, **kwargs):
-        super(Tag, self).__init__(args)
+        super().__init__(args)
         self.attr = self.Attr(**kwargs)
 
     def __unicode__(self):
-        return self.unicode(indent=0)
+        return self.str(indent=0)
     __str__ = __unicode__
 
-    def unicode(self, indent=2):
+    def str(self, indent=2):
         l = []
         SimpleUnicodeVisitor(l.append, indent).visit(self)
         return u("").join(l)
@@ -89,7 +84,7 @@ Namespace = NamespaceMetaclass('Namespace', (object, ), {
 
 class HtmlTag(Tag):
 
-    def unicode(self, indent=2):
+    def str(self, indent=2):
         l = []
         HtmlVisitor(l.append, indent, shortempty=False).visit(self)
         return u("").join(l)
@@ -100,7 +95,7 @@ class HtmlTag(Tag):
 class html(Namespace):
     __tagclass__ = HtmlTag
     __stickyname__ = True
-    __tagspec__ = dict([(x, 1) for x in (
+    __tagspec__ = {x: 1 for x in (
         'a,abbr,acronym,address,applet,area,b,bdo,big,blink,'
         'blockquote,body,br,button,caption,center,cite,code,col,'
         'colgroup,comment,dd,del,dfn,dir,div,dl,dt,em,embed,'
@@ -111,9 +106,9 @@ class html(Namespace):
         'select,small,span,strike,strong,style,sub,sup,table,'
         'tbody,td,textarea,tfoot,th,thead,title,tr,tt,u,ul,xmp,'
         'base,basefont,frame,hr,isindex,param,samp,var'
-    ).split(',') if x])
+    ).split(',') if x}
 
-    class Style(object):
+    class Style:
 
         def __init__(self, **kw):
             for x, y in kw.items():
@@ -121,7 +116,7 @@ class html(Namespace):
                 setattr(self, x, y)
 
 
-class raw(object):
+class raw:
     """just a box that can contain a unicode string that will be
     included directly in the output"""
 
@@ -129,7 +124,7 @@ class raw(object):
         self.uniobj = uniobj
 
 
-class SimpleUnicodeVisitor(object):
+class SimpleUnicodeVisitor:
     """ recursive visitor to write unicode. """
 
     def __init__(self, write, indent=0, curindent=0, shortempty=True):
@@ -160,7 +155,7 @@ class SimpleUnicodeVisitor(object):
     # to avoid clashes with the tag name object
     def __object(self, obj):
         # self.write(obj)
-        self.write(escape(unicode(obj)))
+        self.write(escape(str(obj)))
 
     def raw(self, obj):
         self.write(obj.uniobj)
@@ -217,8 +212,8 @@ class SimpleUnicodeVisitor(object):
             if isinstance(value, raw):
                 insert = value.uniobj
             else:
-                insert = escape(unicode(value))
-            return ' %s="%s"' % (name, insert)
+                insert = escape(str(value))
+            return ' {}="{}"'.format(name, insert)
 
     def getstyle(self, tag):
         """ return attribute list suitable for styling. """
@@ -241,20 +236,20 @@ class SimpleUnicodeVisitor(object):
 
 class HtmlVisitor(SimpleUnicodeVisitor):
 
-    single = dict([(x, 1) for x in
+    single = {x: 1 for x in
                    ('br,img,area,param,col,hr,meta,link,base,'
-                    'input,frame').split(',')])
-    inline = dict([(x, 1) for x in
+                    'input,frame').split(',')}
+    inline = {x: 1 for x in
                    ('a abbr acronym b basefont bdo big br cite code dfn em font '
                     'i img input kbd label q s samp select small span strike '
-                    'strong sub sup textarea tt u var'.split(' '))])
+                    'strong sub sup textarea tt u var'.split(' '))}
 
     def repr_attribute(self, attrs, name):
         if name == 'class_':
             value = getattr(attrs, name)
             if value is None:
                 return
-        return super(HtmlVisitor, self).repr_attribute(attrs, name)
+        return super().repr_attribute(attrs, name)
 
     def _issingleton(self, tagname):
         return tagname in self.single
@@ -270,14 +265,14 @@ class _escape:
             u('"'): u('"'), u('<'): u('<'), u('>'): u('>'),
             u('&'): u('&'), u("'"): u('''),
         }
-        self.charef_rex = re.compile(u("|").join(self.escape.keys()))
+        self.charef_rex = re.compile(u("|").join(list(self.escape.keys())))
 
     def _replacer(self, match):
         return self.escape[match.group(0)]
 
     def __call__(self, ustring):
         """ xml-escape the given unicode string. """
-        ustring = unicode(ustring)
+        ustring = str(ustring)
         return self.charef_rex.sub(self._replacer, ustring)
 
 escape = _escape()
diff --git a/testing/mozbase/mozlog/mozlog/formatters/machformatter.py b/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
index f8f1abc256..3dc005e4bd 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
@@ -10,7 +10,7 @@ try:
 except ImportError:
     blessings = None
 
-import base
+from . import base
 from .process import strstatus
 
 
@@ -20,7 +20,7 @@ def format_seconds(total):
     return '%2d:%05.2f' % (minutes, seconds)
 
 
-class NullTerminal(object):
+class NullTerminal:
 
     def __getattr__(self, name):
         return self._id
@@ -91,7 +91,7 @@ class MachFormatter(base.BaseFormatter):
             if color is not None:
                 action = color(action)
 
-        return "%s %s: %s %s\n" % (time, action, thread, s)
+        return "{} {}: {} {}\n".format(time, action, thread, s)
 
     def _get_test_id(self, data):
         test_id = data.get("test")
@@ -100,7 +100,7 @@ class MachFormatter(base.BaseFormatter):
         return test_id
 
     def _get_file_name(self, test_id):
-        if isinstance(test_id, (str, unicode)):
+        if isinstance(test_id, (str, str)):
             return test_id
 
         if isinstance(test_id, tuple):
@@ -160,14 +160,14 @@ class MachFormatter(base.BaseFormatter):
                     for name, status, expected, message in results:
                         if name is None:
                             name = "[Parent]"
-                        rv.append("%s %s" % (self.format_expected(status, expected), name))
+                        rv.append("{} {}".format(self.format_expected(status, expected), name))
             else:
                 for test_id, results in self.summary_unexpected:
                     test = self._get_file_name(test_id)
                     assert len(results) == 1
                     name, status, expected, messge = results[0]
                     assert name is None
-                    rv.append("%s %s" % (self.format_expected(status, expected), test))
+                    rv.append("{} {}".format(self.format_expected(status, expected), test))
 
         return "\n".join(rv)
 
@@ -181,11 +181,11 @@ class MachFormatter(base.BaseFormatter):
         if expected in ("PASS", "OK"):
             return color(status)
 
-        return color("%s expected %s" % (status, expected))
+        return color("{} expected {}".format(status, expected))
 
     def test_start(self, data):
         self.summary_values["tests"] += 1
-        return "%s" % (self._get_test_id(data),)
+        return "{}".format(self._get_test_id(data))
 
     def test_end(self, data):
         subtests = self._get_subtest_data(data)
@@ -222,7 +222,7 @@ class MachFormatter(base.BaseFormatter):
                 data["status"], expected_str, subtests["pass"], subtests["count"],
                 len(unexpected))
         else:
-            rv = "%s%s" % (data["status"], expected_str)
+            rv = "{}{}".format(data["status"], expected_str)
 
         if unexpected:
             rv += "\n"
@@ -232,7 +232,7 @@ class MachFormatter(base.BaseFormatter):
                 for name, status, expected, message in unexpected:
                     if name is None:
                         name = "[Parent]"
-                    expected_str = "Expected %s, got %s" % (expected, status)
+                    expected_str = "Expected {}, got {}".format(expected, status)
                     rv += "%s\n" % ("\n".join([name, "-" * len(name), expected_str, message]))
                 rv = rv[:-1]
         return rv
@@ -292,9 +292,9 @@ class MachFormatter(base.BaseFormatter):
 
         if "command" in data and data["process"] not in self._known_pids:
             self._known_pids.add(data["process"])
-            rv.append('(pid:%s) Full command: %s' % (data["process"], data["command"]))
+            rv.append('(pid:{}) Full command: {}'.format(data["process"], data["command"]))
 
-        rv.append('(pid:%s) "%s"' % (data["process"], data["data"]))
+        rv.append('(pid:{}) "{}"'.format(data["process"], data["data"]))
         return "\n".join(rv)
 
     def crash(self, data):
@@ -334,11 +334,11 @@ class MachFormatter(base.BaseFormatter):
         rv = "Started process `%s`" % data['process']
         desc = data.get('command')
         if desc:
-            rv = '%s (%s)' % (rv, desc)
+            rv = '{} ({})'.format(rv, desc)
         return rv
 
     def process_exit(self, data):
-        return "%s: %s" % (data['process'], strstatus(data['exitcode']))
+        return "{}: {}".format(data['process'], strstatus(data['exitcode']))
 
     def log(self, data):
         level = data.get("level").upper()
@@ -354,7 +354,7 @@ class MachFormatter(base.BaseFormatter):
         if data.get('component'):
             rv = " ".join([data["component"], level, data["message"]])
         else:
-            rv = "%s %s" % (level, data["message"])
+            rv = "{} {}".format(level, data["message"])
 
         if "stack" in data:
             rv += "\n%s" % data["stack"]
diff --git a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py
index 71152d4558..81d1f0e643 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py
@@ -61,7 +61,7 @@ class TbplFormatter(BaseFormatter):
 
     def _log(self, data):
         if data.get('component'):
-            message = "%s %s" % (data["component"], data["message"])
+            message = "{} {}".format(data["component"], data["message"])
         else:
             message = data["message"]
 
@@ -78,12 +78,12 @@ class TbplFormatter(BaseFormatter):
     def process_start(self, data):
         msg = "TEST-INFO | started process %s" % data['process']
         if 'command' in data:
-            msg = '%s (%s)' % (msg, data['command'])
+            msg = '{} ({})'.format(msg, data['command'])
         return msg + '\n'
 
     @output_subtests
     def process_exit(self, data):
-        return "TEST-INFO | %s: %s\n" % (data['process'],
+        return "TEST-INFO | {}: {}\n".format(data['process'],
                                          strstatus(data['exitcode']))
 
     @output_subtests
@@ -91,7 +91,7 @@ class TbplFormatter(BaseFormatter):
         id = data["test"] if "test" in data else "pid: %s" % data["process"]
 
         signature = data["signature"] if data["signature"] else "unknown top frame"
-        rv = ["PROCESS-CRASH | %s | application crashed [%s]" % (id, signature)]
+        rv = ["PROCESS-CRASH | {} | application crashed [{}]".format(id, signature)]
 
         if data.get("minidump_path"):
             rv.append("Crash dump filename: %s" % data["minidump_path"])
@@ -149,7 +149,7 @@ class TbplFormatter(BaseFormatter):
         if "expected" in data:
             if not message:
                 message = "- expected %s" % data["expected"]
-            failure_line = "TEST-UNEXPECTED-%s | %s | %s %s\n" % (
+            failure_line = "TEST-UNEXPECTED-{} | {} | {} {}\n".format(
                 data["status"], data["test"], data["subtest"],
                 message)
             if data["expected"] != "PASS":
@@ -157,7 +157,7 @@ class TbplFormatter(BaseFormatter):
                 return failure_line + info_line
             return failure_line
 
-        return "TEST-%s | %s | %s %s\n" % (
+        return "TEST-{} | {} | {} {}\n".format(
             data["status"], data["test"], data["subtest"],
             message)
 
@@ -200,14 +200,14 @@ class TbplFormatter(BaseFormatter):
                     message += "\nREFTEST   IMAGE: data:image/png;base64,%(image1)s" \
                                % screenshots[0]["screenshot"]
 
-            failure_line = "TEST-UNEXPECTED-%s | %s | %s\n" % (
+            failure_line = "TEST-UNEXPECTED-{} | {} | {}\n".format(
                 data["status"], test_id, message)
 
             if data["expected"] not in ("PASS", "OK"):
                 expected_msg = "expected %s | " % data["expected"]
             else:
                 expected_msg = ""
-            info_line = "TEST-INFO %s%s\n" % (expected_msg, duration_msg)
+            info_line = "TEST-INFO {}{}\n".format(expected_msg, duration_msg)
 
             return failure_line + info_line
 
@@ -224,7 +224,7 @@ class TbplFormatter(BaseFormatter):
         return "SUITE-END | took %is\n" % time
 
     def test_id(self, test_id):
-        if isinstance(test_id, (str, unicode)):
+        if isinstance(test_id, (str, str)):
             return test_id
         else:
             return tuple(test_id)
diff --git a/testing/mozbase/mozlog/mozlog/formatters/unittest.py b/testing/mozbase/mozlog/mozlog/formatters/unittest.py
index 254205eae5..7618d25758 100755
--- a/testing/mozbase/mozlog/mozlog/formatters/unittest.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/unittest.py
@@ -3,7 +3,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import base
+from . import base
 
 
 class UnittestFormatter(base.BaseFormatter):
diff --git a/testing/mozbase/mozlog/mozlog/formatters/xunit.py b/testing/mozbase/mozlog/mozlog/formatters/xunit.py
index 3930afa3e5..fcf42cbe0b 100644
--- a/testing/mozbase/mozlog/mozlog/formatters/xunit.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/xunit.py
@@ -1,13 +1,13 @@
 import types
 from xml.etree import ElementTree
 
-import base
+from . import base
 
 
 def format_test_id(test_id):
     """Take a test id and return something that looks a bit like
     a class path"""
-    if type(test_id) not in types.StringTypes:
+    if type(test_id) not in (str,):
         # Not sure how to deal with reftests yet
         raise NotImplementedError
 
@@ -75,8 +75,8 @@ class XUnitFormatter(base.BaseFormatter):
                 result = ElementTree.SubElement(test, "failure")
                 self.failures += 1
 
-            result.attrib["message"] = "Expected %s, got %s" % (data["expected"], data["status"])
-            result.text = '%s\n%s' % (data.get('stack', ''), data.get('message', ''))
+            result.attrib["message"] = "Expected {}, got {}".format(data["expected"], data["status"])
+            result.text = '{}\n{}'.format(data.get('stack', ''), data.get('message', ''))
 
         elif data["status"] == "SKIP":
             result = ElementTree.SubElement(test, "skipped")
diff --git a/testing/mozbase/mozlog/mozlog/handlers/base.py b/testing/mozbase/mozlog/mozlog/handlers/base.py
index be4df21f9f..0cfa31727d 100644
--- a/testing/mozbase/mozlog/mozlog/handlers/base.py
+++ b/testing/mozbase/mozlog/mozlog/handlers/base.py
@@ -8,7 +8,7 @@ import codecs
 from ..structuredlog import log_levels
 
 
-class BaseHandler(object):
+class BaseHandler:
     """A base handler providing message handling facilities to
     derived classes.
 
@@ -95,7 +95,7 @@ class StreamHandler(BaseHandler):
         if not formatted:
             return
         with self._lock:
-            if isinstance(formatted, unicode):
+            if isinstance(formatted, str):
                 self.stream.write(formatted.encode("utf-8", "replace"))
             elif isinstance(formatted, str):
                 self.stream.write(formatted)
diff --git a/testing/mozbase/mozlog/mozlog/handlers/statushandler.py b/testing/mozbase/mozlog/mozlog/handlers/statushandler.py
index b5aeb1b537..b762eaeb44 100644
--- a/testing/mozbase/mozlog/mozlog/handlers/statushandler.py
+++ b/testing/mozbase/mozlog/mozlog/handlers/statushandler.py
@@ -15,7 +15,7 @@ RunSummary = namedtuple("RunSummary",
                          "action_counts"))
 
 
-class StatusHandler(object):
+class StatusHandler:
     """A handler used to determine an overall status for a test run according
     to a sequence of log messages."""
 
diff --git a/testing/mozbase/mozlog/mozlog/handlers/valgrindhandler.py b/testing/mozbase/mozlog/mozlog/handlers/valgrindhandler.py
index 5bedfb9abe..fd21570dab 100644
--- a/testing/mozbase/mozlog/mozlog/handlers/valgrindhandler.py
+++ b/testing/mozbase/mozlog/mozlog/handlers/valgrindhandler.py
@@ -19,7 +19,7 @@ class ValgrindHandler(BaseHandler):
             self.inner(tmp)
 
 
-class ValgrindFilter(object):
+class ValgrindFilter:
     '''
     A class for handling Valgrind output.
 
@@ -123,14 +123,14 @@ class ValgrindFilter(object):
                 # fields from the incoming message, since there's nowhere
                 # else to get them from.
                 output_message = {  # Mandatory fields
-                    u"action": "valgrind_error",
-                    u"time":   msg["time"],
-                    u"thread": msg["thread"],
-                    u"pid":    msg["pid"],
-                    u"source": msg["source"],
+                    "action": "valgrind_error",
+                    "time":   msg["time"],
+                    "thread": msg["thread"],
+                    "pid":    msg["pid"],
+                    "source": msg["source"],
                     # valgrind_error specific fields
-                    u"primary":   self.curr_failure_msg,
-                    u"secondary": self.buffered_lines}
+                    "primary":   self.curr_failure_msg,
+                    "secondary": self.buffered_lines}
                 self.curr_failure_msg = ""
                 self.buffered_lines = []
 
diff --git a/testing/mozbase/mozlog/mozlog/logtypes.py b/testing/mozbase/mozlog/mozlog/logtypes.py
index d5ebff93cc..4ab4f86d84 100644
--- a/testing/mozbase/mozlog/mozlog/logtypes.py
+++ b/testing/mozbase/mozlog/mozlog/logtypes.py
@@ -7,7 +7,7 @@ missing = object()
 no_default = object()
 
 
-class log_action(object):
+class log_action:
 
     def __init__(self, *args):
         self.args = {}
@@ -83,7 +83,7 @@ class log_action(object):
             if name not in values:
                 values[name] = self.args[name].default
 
-        for key, value in values.iteritems():
+        for key, value in values.items():
             if key in self.args:
                 out_value = self.args[key](value)
                 if out_value is not missing:
@@ -94,12 +94,12 @@ class log_action(object):
         return data
 
     def convert_known(self, **kwargs):
-        known_kwargs = {name: value for name, value in kwargs.iteritems()
+        known_kwargs = {name: value for name, value in kwargs.items()
                         if name in self.args}
         return self.convert(**known_kwargs)
 
 
-class DataType(object):
+class DataType:
 
     def __init__(self, name, default=no_default, optional=False):
         self.name = name
@@ -126,17 +126,17 @@ class DataType(object):
 class Unicode(DataType):
 
     def convert(self, data):
-        if isinstance(data, unicode):
+        if isinstance(data, str):
             return data
         if isinstance(data, str):
             return data.decode("utf8", "replace")
-        return unicode(data)
+        return str(data)
 
 
 class TestId(DataType):
 
     def convert(self, data):
-        if isinstance(data, unicode):
+        if isinstance(data, str):
             return data
         elif isinstance(data, bytes):
             return data.decode("utf-8", "replace")
diff --git a/testing/mozbase/mozlog/mozlog/proxy.py b/testing/mozbase/mozlog/mozlog/proxy.py
index 44ce242256..0c69728220 100644
--- a/testing/mozbase/mozlog/mozlog/proxy.py
+++ b/testing/mozbase/mozlog/mozlog/proxy.py
@@ -5,7 +5,7 @@
 from .structuredlog import get_default_logger
 
 
-class ProxyLogger(object):
+class ProxyLogger:
     """
     A ProxyLogger behaves like a
     :class:`mozlog.structuredlog.StructuredLogger`.
diff --git a/testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py b/testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py
index 811ee38e38..03090fe8a9 100644
--- a/testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py
+++ b/testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py
@@ -12,15 +12,15 @@ def pytest_addoption(parser):
     # Pytest's parser doesn't have the add_argument_group method Mozlog expects.
     group = parser.getgroup('mozlog')
 
-    for name, (_class, _help) in mozlog.commandline.log_formatters.iteritems():
-        group.addoption('--log-{0}'.format(name), action='append', help=_help)
+    for name, (_class, _help) in mozlog.commandline.log_formatters.items():
+        group.addoption('--log-{}'.format(name), action='append', help=_help)
 
-    formatter_options = mozlog.commandline.fmt_options.iteritems()
+    formatter_options = mozlog.commandline.fmt_options.items()
     for name, (_class, _help, formatters, action) in formatter_options:
         for formatter in formatters:
             if formatter in mozlog.commandline.log_formatters:
                 group.addoption(
-                    '--log-{0}-{1}'.format(formatter, name),
+                    '--log-{}-{}'.format(formatter, name),
                     action=action,
                     help=_help)
 
@@ -31,7 +31,7 @@ def pytest_configure(config):
         config.pluginmanager.register(MozLog())
 
 
-class MozLog(object):
+class MozLog:
 
     def __init__(self):
         self.results = {}
@@ -79,7 +79,7 @@ class MozLog(object):
         elif report.failed:
             status = 'FAIL' if report.when == 'call' else 'ERROR'
             crash = report.longrepr.reprcrash  # here longrepr is a ReprExceptionInfo
-            message = "{0} (line {1})".format(crash.message, crash.lineno)
+            message = "{} (line {})".format(crash.message, crash.lineno)
             stack = report.longrepr.reprtraceback
         elif report.skipped:  # indicates true skip
             status = expected = 'SKIP'
diff --git a/testing/mozbase/mozlog/mozlog/reader.py b/testing/mozbase/mozlog/mozlog/reader.py
index c00ec6d383..00a4343ee7 100644
--- a/testing/mozbase/mozlog/mozlog/reader.py
+++ b/testing/mozbase/mozlog/mozlog/reader.py
@@ -50,7 +50,7 @@ def each_log(log_iter, action_map):
             action_map[item["action"]](item)
 
 
-class LogHandler(object):
+class LogHandler:
     """Base class for objects that act as log handlers. A handler is a callable
     that takes a log entry as the only argument.
 
diff --git a/testing/mozbase/mozlog/mozlog/scripts/__init__.py b/testing/mozbase/mozlog/mozlog/scripts/__init__.py
index 53f9146c92..869fb81360 100644
--- a/testing/mozbase/mozlog/mozlog/scripts/__init__.py
+++ b/testing/mozbase/mozlog/mozlog/scripts/__init__.py
@@ -1,9 +1,9 @@
 #!/usr/bin/env python
 
 import argparse
-import unstable
-import format as formatlog
-import logmerge
+from . import unstable
+from . import format as formatlog
+from . import logmerge
 
 
 def get_parser():
@@ -16,7 +16,7 @@ def get_parser():
 
     sub_parser = parser.add_subparsers(title='Subcommands')
 
-    for command, (parser_func, main_func) in commands.iteritems():
+    for command, (parser_func, main_func) in commands.items():
         parent = parser_func(False)
         command_parser = sub_parser.add_parser(command,
                                                description=parent.description,
diff --git a/testing/mozbase/mozlog/mozlog/scripts/format.py b/testing/mozbase/mozlog/mozlog/scripts/format.py
index 1644e4b956..627ff104a4 100644
--- a/testing/mozbase/mozlog/mozlog/scripts/format.py
+++ b/testing/mozbase/mozlog/mozlog/scripts/format.py
@@ -12,7 +12,7 @@ def get_parser(add_help=True):
                         help="Filename to read from, defaults to stdin")
     parser.add_argument("--output", action="store", default=None,
                         help="Filename to write to, defaults to stdout")
-    parser.add_argument("format", choices=commandline.log_formatters.keys(),
+    parser.add_argument("format", choices=list(commandline.log_formatters.keys()),
                         help="Format to use")
     return parser
 
diff --git a/testing/mozbase/mozlog/mozlog/scripts/logmerge.py b/testing/mozbase/mozlog/mozlog/scripts/logmerge.py
index 1185dc6055..89ea8a2ad5 100644
--- a/testing/mozbase/mozlog/mozlog/scripts/logmerge.py
+++ b/testing/mozbase/mozlog/mozlog/scripts/logmerge.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
 import argparse
 import json
 import os
@@ -61,7 +60,7 @@ def main(**kwargs):
         output = sys.stdout
     else:
         output = open(kwargs["output"], "w")
-    readers = [read(open(filename, 'r')) for filename in kwargs["files"]]
+    readers = [read(open(filename)) for filename in kwargs["files"]]
     start_events = [process_until_suite_start(reader, output) for reader in readers]
     validate_start_events(start_events)
     merged_start_event = merge_start_events(start_events)
diff --git a/testing/mozbase/mozlog/mozlog/scripts/unstable.py b/testing/mozbase/mozlog/mozlog/scripts/unstable.py
index 2b31bba52e..9839c175e4 100644
--- a/testing/mozbase/mozlog/mozlog/scripts/unstable.py
+++ b/testing/mozbase/mozlog/mozlog/scripts/unstable.py
@@ -73,17 +73,17 @@ def group_results(data):
 def print_results(data):
     for run_info, tests in data.iteritems():
         run_str = " ".join("%s:%s" % (k, v) for k, v in run_info) if run_info else "No Run Info"
-        print run_str
-        print "=" * len(run_str)
+        print(run_str)
+        print("=" * len(run_str))
         print_run(tests)
 
 
 def print_run(tests):
     for test, subtests in sorted(tests.items()):
-        print "\n" + str(test)
-        print "-" * len(test)
+        print("\n" + str(test))
+        print("-" * len(test))
         for name, results in subtests.iteritems():
-            print "[%s]: %s" % (name if name is not None else "",
+            print("[%s]: %s" % (name if name is not None else "",)
                                 " ".join("%s (%i)" % (k, v) for k, v in results.iteritems()))
 
 
@@ -106,7 +106,7 @@ def main(**kwargs):
         unstable = group_results(unstable)
 
     if kwargs["json"]:
-        print json.dumps(unstable)
+        print(json.dumps(unstable))
     else:
         if not kwargs["group"]:
             print_results(unstable)
diff --git a/testing/mozbase/mozlog/mozlog/stdadapter.py b/testing/mozbase/mozlog/mozlog/stdadapter.py
index fc967c0a61..d4459d9c75 100644
--- a/testing/mozbase/mozlog/mozlog/stdadapter.py
+++ b/testing/mozbase/mozlog/mozlog/stdadapter.py
@@ -1,6 +1,6 @@
 import logging
 
-from structuredlog import StructuredLogger, log_levels
+from .structuredlog import StructuredLogger, log_levels
 
 
 class UnstructuredHandler(logging.Handler):
@@ -20,7 +20,7 @@ class UnstructuredHandler(logging.Handler):
         self.emit(record)
 
 
-class LoggingWrapper(object):
+class LoggingWrapper:
 
     def __init__(self, wrapped):
         self.wrapped = wrapped
diff --git a/testing/mozbase/mozlog/mozlog/structuredlog.py b/testing/mozbase/mozlog/mozlog/structuredlog.py
index fb41f2112e..45e7b32ff6 100644
--- a/testing/mozbase/mozlog/mozlog/structuredlog.py
+++ b/testing/mozbase/mozlog/mozlog/structuredlog.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import unicode_literals
 
 from multiprocessing import current_process
 from threading import current_thread, Lock
@@ -11,8 +10,8 @@ import sys
 import time
 import traceback
 
-from logtypes import Unicode, TestId, Status, SubStatus, Dict, List, Int, Any, Tuple
-from logtypes import log_action, convertor_registry
+from .logtypes import Unicode, TestId, Status, SubStatus, Dict, List, Int, Any, Tuple
+from .logtypes import log_action, convertor_registry
 
 """Structured Logging for recording test results.
 
@@ -92,8 +91,8 @@ def set_default_logger(default_logger):
 
     _default_logger_name = default_logger.name
 
-log_levels = dict((k.upper(), v) for v, k in
-                  enumerate(["critical", "error", "warning", "info", "debug"]))
+log_levels = {k.upper(): v for v, k in
+                  enumerate(["critical", "error", "warning", "info", "debug"])}
 
 lint_levels = ["ERROR", "WARNING"]
 
@@ -103,7 +102,7 @@ def log_actions():
     return set(convertor_registry.keys())
 
 
-class LoggerState(object):
+class LoggerState:
 
     def __init__(self):
         self.handlers = []
@@ -112,13 +111,13 @@ class LoggerState(object):
         self.component_states = {}
 
 
-class ComponentState(object):
+class ComponentState:
 
     def __init__(self):
         self.filter_ = None
 
 
-class StructuredLogger(object):
+class StructuredLogger:
     _lock = Lock()
     _logger_states = {}
     """Create a structured logger with the given name
@@ -222,8 +221,8 @@ class StructuredLogger(object):
                 except Exception:
                     # Write the exception details directly to stderr because
                     # log() would call this method again which is currently locked.
-                    print >> sys.__stderr__, '%s: Failure calling log handler:' % __name__
-                    print >> sys.__stderr__, traceback.format_exc()
+                    print('%s: Failure calling log handler:' % __name__, file=sys.__stderr__)
+                    print(traceback.format_exc(), file=sys.__stderr__)
 
     def _make_log_data(self, action, data):
         all_data = {"action": action,
@@ -433,7 +432,7 @@ def _log_func(level_name):
                 exc_info = sys.exc_info()
             if exc_info != (None, None, None):
                 bt = traceback.format_exception(*exc_info)
-                data["stack"] = u"\n".join(bt)
+                data["stack"] = "\n".join(bt)
 
         data["level"] = level_name
         self._log_data("log", data)
@@ -490,7 +489,7 @@ for level_name in lint_levels:
     setattr(StructuredLogger, name, _lint_func(level_name))
 
 
-class StructuredLogFileLike(object):
+class StructuredLogFileLike:
     """Wrapper for file-like objects to redirect writes to logger
     instead. Each call to `write` becomes a single log entry of type `log`.
 
@@ -514,7 +513,7 @@ class StructuredLogFileLike(object):
         if data.endswith("\r"):
             data = data[:-1]
         if self.prefix is not None:
-            data = "%s: %s" % (self.prefix, data)
+            data = "{}: {}".format(self.prefix, data)
         self.log_func(data)
 
     def flush(self):
diff --git a/testing/mozbase/mozlog/mozlog/unstructured/loggingmixin.py b/testing/mozbase/mozlog/mozlog/unstructured/loggingmixin.py
index 41a67cf09e..5700af1000 100644
--- a/testing/mozbase/mozlog/mozlog/unstructured/loggingmixin.py
+++ b/testing/mozbase/mozlog/mozlog/unstructured/loggingmixin.py
@@ -8,7 +8,7 @@ from .logger import (
 )
 
 
-class LoggingMixin(object):
+class LoggingMixin:
     """Expose a subset of logging functions to an inheriting class."""
 
     def set_logger(self, logger_instance=None, name=None):
diff --git a/testing/mozbase/mozlog/mozlog/unstructured/loglistener.py b/testing/mozbase/mozlog/mozlog/unstructured/loglistener.py
index d567301805..77d08f1ed9 100644
--- a/testing/mozbase/mozlog/mozlog/unstructured/loglistener.py
+++ b/testing/mozbase/mozlog/mozlog/unstructured/loglistener.py
@@ -2,21 +2,21 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import SocketServer
+import socketserver
 import socket
 import json
 
 
-class LogMessageServer(SocketServer.TCPServer):
+class LogMessageServer(socketserver.TCPServer):
 
     def __init__(self, server_address, logger, message_callback=None, timeout=3):
-        SocketServer.TCPServer.__init__(self, server_address, LogMessageHandler)
+        socketserver.TCPServer.__init__(self, server_address, LogMessageHandler)
         self._logger = logger
         self._message_callback = message_callback
         self.timeout = timeout
 
 
-class LogMessageHandler(SocketServer.BaseRequestHandler):
+class LogMessageHandler(socketserver.BaseRequestHandler):
     """Processes output from a connected log source, logging to an
     existing logger upon receipt of a well-formed log messsage."""
 
diff --git a/testing/mozbase/mozlog/tests/test_logger.py b/testing/mozbase/mozlog/tests/test_logger.py
index 30f4eb5699..ea35624959 100644
--- a/testing/mozbase/mozlog/tests/test_logger.py
+++ b/testing/mozbase/mozlog/tests/test_logger.py
@@ -80,7 +80,7 @@ class TestStructuredLogging(unittest.TestCase):
         The actual message should contain no fields other than the timestamp
         field and those present in expected."""
 
-        self.assertTrue(isinstance(actual['_time'], (int, long)))
+        self.assertTrue(isinstance(actual['_time'], int))
 
         for k, v in expected.items():
             self.assertEqual(v, actual[k])
diff --git a/testing/mozbase/mozlog/tests/test_structured.py b/testing/mozbase/mozlog/tests/test_structured.py
index ab4b5f5826..a7b621ca7a 100644
--- a/testing/mozbase/mozlog/tests/test_structured.py
+++ b/testing/mozbase/mozlog/tests/test_structured.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 import argparse
 import json
 import optparse
@@ -19,9 +18,11 @@ from mozlog import (
     handlers,
     formatters,
 )
+import six
+unichr = chr
 
 
-class TestHandler(object):
+class TestHandler:
 
     def __init__(self):
         self.items = []
@@ -55,20 +56,20 @@ class BaseStructuredTest(unittest.TestCase):
         all_expected = {"pid": os.getpid(),
                         "thread": "MainThread",
                         "source": "test"}
-        specials = set(["time"])
+        specials = {"time"}
 
         all_expected.update(expected)
-        for key, value in all_expected.iteritems():
+        for key, value in all_expected.items():
             self.assertEqual(actual[key], value)
 
-        self.assertEquals(set(all_expected.keys()) |
+        self.assertEqual(set(all_expected.keys()) |
                           specials, set(actual.keys()))
 
 
 class TestStatusHandler(BaseStructuredTest):
 
     def setUp(self):
-        super(TestStatusHandler, self).setUp()
+        super().setUp()
         self.handler = handlers.StatusHandler()
         self.logger.add_handler(self.handler)
 
@@ -253,8 +254,8 @@ class TestStructuredLog(BaseStructuredTest):
                                 "test": "test2"})
         self.logger.test_end("test2", "PASS", expected="PASS")
         last_item = self.pop_last_item()
-        self.assertEquals(last_item["action"], "log")
-        self.assertEquals(last_item["level"], "ERROR")
+        self.assertEqual(last_item["action"], "log")
+        self.assertEqual(last_item["level"], "ERROR")
         self.assertTrue(last_item["message"].startswith(
             "test_end for test2 logged while not in progress. Logged with data: {"))
         self.logger.suite_end()
@@ -265,8 +266,8 @@ class TestStructuredLog(BaseStructuredTest):
                                 "tests": []})
         self.logger.suite_start([])
         last_item = self.pop_last_item()
-        self.assertEquals(last_item["action"], "log")
-        self.assertEquals(last_item["level"], "ERROR")
+        self.assertEqual(last_item["action"], "log")
+        self.assertEqual(last_item["level"], "ERROR")
         self.logger.suite_end()
 
     def test_suite_end_no_start(self):
@@ -277,16 +278,16 @@ class TestStructuredLog(BaseStructuredTest):
         self.assert_log_equals({"action": "suite_end"})
         self.logger.suite_end()
         last_item = self.pop_last_item()
-        self.assertEquals(last_item["action"], "log")
-        self.assertEquals(last_item["level"], "ERROR")
+        self.assertEqual(last_item["action"], "log")
+        self.assertEqual(last_item["level"], "ERROR")
 
     def test_multiple_loggers_suite_start(self):
         logger1 = structuredlog.StructuredLogger("test")
         self.logger.suite_start([])
         logger1.suite_start([])
         last_item = self.pop_last_item()
-        self.assertEquals(last_item["action"], "log")
-        self.assertEquals(last_item["level"], "ERROR")
+        self.assertEqual(last_item["action"], "log")
+        self.assertEqual(last_item["level"], "ERROR")
 
     def test_multiple_loggers_test_start(self):
         logger1 = structuredlog.StructuredLogger("test")
@@ -294,8 +295,8 @@ class TestStructuredLog(BaseStructuredTest):
         self.logger.test_start("test")
         logger1.test_start("test")
         last_item = self.pop_last_item()
-        self.assertEquals(last_item["action"], "log")
-        self.assertEquals(last_item["level"], "ERROR")
+        self.assertEqual(last_item["action"], "log")
+        self.assertEqual(last_item["level"], "ERROR")
 
     def test_process(self):
         self.logger.process_output(1234, "test output")
@@ -407,10 +408,10 @@ class TestTypeConversions(BaseStructuredTest):
     def test_tuple(self):
         self.logger.suite_start([])
         self.logger.test_start(("\xf0\x90\x8d\x84\xf0\x90\x8c\xb4\xf0\x90\x8d\x83\xf0\x90\x8d\x84",
-                                42, u"\u16a4"))
+                                42, "\u16a4"))
         self.assert_log_equals({"action": "test_start",
-                                "test": (u'\U00010344\U00010334\U00010343\U00010344',
-                                         u"42", u"\u16a4")})
+                                "test": ('\U00010344\U00010334\U00010343\U00010344',
+                                         "42", "\u16a4")})
         self.logger.suite_end()
 
     def test_non_string_messages(self):
@@ -434,7 +435,7 @@ class TestTypeConversions(BaseStructuredTest):
             self.logger.info("☺")
             logfile.seek(0)
             data = logfile.readlines()[-1].strip()
-            self.assertEquals(data, "☺")
+            self.assertEqual(data, "☺")
             self.logger.suite_end()
 
     def test_arguments(self):
@@ -784,7 +785,7 @@ class TestXUnitFormatter(FormatterTest):
         self.logger.suite_end()
 
         root = self.log_as_xml()
-        self.assertEquals('Expected OK, got FAIL', root.find(
+        self.assertEqual('Expected OK, got FAIL', root.find(
             'testcase/failure').get('message'))
 
     def test_suite_attrs(self):
@@ -858,7 +859,7 @@ class TestCommandline(unittest.TestCase):
     def test_setup_logging_optparse_unicode(self):
         parser = optparse.OptionParser()
         commandline.add_logging_group(parser)
-        args, _ = parser.parse_args([u"--log-raw=-"])
+        args, _ = parser.parse_args(["--log-raw=-"])
         logger = commandline.setup_logging("test_optparse_unicode", args, {})
         self.assertEqual(len(logger.handlers), 1)
         self.assertEqual(logger.handlers[0].stream, sys.stdout)
@@ -924,13 +925,13 @@ class TestBuffer(BaseStructuredTest):
         all_expected = {"pid": os.getpid(),
                         "thread": "MainThread",
                         "source": "testBuffer"}
-        specials = set(["time"])
+        specials = {"time"}
 
         all_expected.update(expected)
-        for key, value in all_expected.iteritems():
+        for key, value in all_expected.items():
             self.assertEqual(actual[key], value)
 
-        self.assertEquals(set(all_expected.keys()) |
+        self.assertEqual(set(all_expected.keys()) |
                           specials, set(actual.keys()))
 
     def setUp(self):
@@ -985,11 +986,11 @@ class TestBuffer(BaseStructuredTest):
                                 "test": "test1"})
 
         # The buffer's actual size never grows beyond the specified limit.
-        self.assertEquals(len(self.handler._buffer), 4)
+        self.assertEqual(len(self.handler._buffer), 4)
 
         self.logger.test_status("test1", "sub8", status="FAIL")
         # The number of messages deleted comes back in a list.
-        self.assertEquals([4], self.logger.send_message("buffer", "flush"))
+        self.assertEqual([4], self.logger.send_message("buffer", "flush"))
 
         # When the buffer is dumped, the failure is the last thing logged
         self.assert_log_equals({"action": "test_status",
@@ -1025,7 +1026,7 @@ class TestReader(unittest.TestCase):
                 {"action": "action_1", "data": "data_1"}]
 
         f = self.to_file_like(data)
-        self.assertEquals(data, list(reader.read(f)))
+        self.assertEqual(data, list(reader.read(f)))
 
     def test_imap_log(self):
         data = [{"action": "action_0", "data": "data_0"},
@@ -1042,7 +1043,7 @@ class TestReader(unittest.TestCase):
         res_iter = reader.imap_log(reader.read(f),
                                    {"action_0": f_action_0,
                                     "action_1": f_action_1})
-        self.assertEquals([("action_0", "data_0"), ("action_1", "data_1")],
+        self.assertEqual([("action_0", "data_0"), ("action_1", "data_1")],
                           list(res_iter))
 
     def test_each_log(self):
@@ -1064,7 +1065,7 @@ class TestReader(unittest.TestCase):
                         {"action_0": f_action_0,
                          "action_1": f_action_1})
 
-        self.assertEquals({"action_0": 1, "action_1": 2}, count)
+        self.assertEqual({"action_0": 1, "action_1": 2}, count)
 
     def test_handler(self):
         data = [{"action": "action_0", "data": "data_0"},
@@ -1091,8 +1092,8 @@ class TestReader(unittest.TestCase):
         handler = ReaderTestHandler()
         reader.handle_log(reader.read(f), handler)
 
-        self.assertEquals(handler.action_0_count, 1)
-        self.assertEquals(handler.action_1_count, 1)
+        self.assertEqual(handler.action_0_count, 1)
+        self.assertEqual(handler.action_1_count, 1)
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/testing/mozbase/moznetwork/moznetwork/__init__.py b/testing/mozbase/moznetwork/moznetwork/__init__.py
index df2097cb02..e3423e71ac 100644
--- a/testing/mozbase/moznetwork/moznetwork/__init__.py
+++ b/testing/mozbase/moznetwork/moznetwork/__init__.py
@@ -14,13 +14,13 @@ Example usage:
 
   try:
       ip = moznetwork.get_ip()
-      print "The external IP of your machine is '%s'" % ip
+      print("The external IP of your machine is '%s'" % ip)
   except moznetwork.NetworkError:
-      print "Unable to determine IP address of machine"
+      print("Unable to determine IP address of machine")
       raise
 
 """
 
-from moznetwork import get_ip
+from .moznetwork import get_ip
 
 __all__ = ['get_ip']
diff --git a/testing/mozbase/moznetwork/moznetwork/moznetwork.py b/testing/mozbase/moznetwork/moznetwork/moznetwork.py
index 5376496039..03b9cf15c3 100644
--- a/testing/mozbase/moznetwork/moznetwork/moznetwork.py
+++ b/testing/mozbase/moznetwork/moznetwork/moznetwork.py
@@ -51,7 +51,7 @@ def _get_interface_list():
                  socket.inet_ntoa(namestr[i + 20:i + 24]))
                 for i in range(0, outbytes, struct_size)]
 
-    except IOError:
+    except OSError:
         raise NetworkError('Unable to call ioctl with SIOCGIFCONF')
 
 
@@ -72,13 +72,13 @@ def _parse_ifconfig():
 
     # Attempt to determine the default interface in use.
     default_iface = _proc_matches(['route', '-n', 'get', 'default'],
-                                  'interface: (\w+)')
+                                  r'interface: (\w+)')
 
     if default_iface:
         addr_list = _proc_matches(['ifconfig', default_iface[0]],
-                                  'inet (\d+.\d+.\d+.\d+)')
+                                  r'inet (\d+.\d+.\d+.\d+)')
         if addr_list:
-            logger.debug('Default interface: [%s] %s' % (default_iface[0],
+            logger.debug('Default interface: [{}] {}'.format(default_iface[0],
                                                          addr_list[0]))
             if not addr_list[0].startswith('127.'):
                 return addr_list[0]
@@ -86,16 +86,16 @@ def _parse_ifconfig():
     # Iterate over plausible interfaces if we didn't find a suitable default.
     for iface in ['en%s' % i for i in range(10)]:
         addr_list = _proc_matches(['ifconfig', iface],
-                                  'inet (\d+.\d+.\d+.\d+)')
+                                  r'inet (\d+.\d+.\d+.\d+)')
         if addr_list:
-            logger.debug('Interface: [%s] %s' % (iface, addr_list[0]))
+            logger.debug('Interface: [{}] {}'.format(iface, addr_list[0]))
             if not addr_list[0].startswith('127.'):
                 return addr_list[0]
 
     # Just return any that isn't localhost. If we can't find one, we have
     # failed.
     addrs = _proc_matches(['ifconfig'],
-                          'inet (\d+.\d+.\d+.\d+)')
+                          r'inet (\d+.\d+.\d+.\d+)')
     try:
         return [addr for addr in addrs if not addr.startswith('127.')][0]
     except IndexError:
@@ -134,7 +134,7 @@ def get_ip():
         if mozinfo.isLinux:
             interfaces = _get_interface_list()
             for ifconfig in interfaces:
-                logger.debug('Interface: [%s] %s' % (ifconfig[0], ifconfig[1]))
+                logger.debug('Interface: [{}] {}'.format(ifconfig[0], ifconfig[1]))
                 if ifconfig[0] == 'lo':
                     continue
                 else:
diff --git a/testing/mozbase/moznetwork/tests/test.py b/testing/mozbase/moznetwork/tests/test.py
index 79eee6b038..e026010feb 100644
--- a/testing/mozbase/moznetwork/tests/test.py
+++ b/testing/mozbase/moznetwork/tests/test.py
@@ -4,7 +4,7 @@ Unit-Tests for moznetwork
 """
 
 import os
-import mock
+from unittest import mock
 import mozinfo
 import moznetwork
 import re
@@ -26,8 +26,8 @@ def verify_ip_in_list(ip):
 
     # Regex to match IPv4 addresses.
     # 0-255.0-255.0-255.0-255, note order is important here.
-    regexip = re.compile("((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}"
-                         "(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)")
+    regexip = re.compile(r"((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}"
+                         r"(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)")
 
     if mozinfo.isLinux or mozinfo.isMac or mozinfo.isBsd:
         # if "/sbin/ifconfig" exist, use it because it may not be in the
diff --git a/testing/mozbase/mozprocess/mozprocess/__init__.py b/testing/mozbase/mozprocess/mozprocess/__init__.py
index 0b238c2b25..fadb464639 100644
--- a/testing/mozbase/mozprocess/mozprocess/__init__.py
+++ b/testing/mozbase/mozprocess/mozprocess/__init__.py
@@ -3,6 +3,5 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 from .processhandler import *
diff --git a/testing/mozbase/mozprocess/mozprocess/processhandler.py b/testing/mozbase/mozprocess/mozprocess/processhandler.py
index 661a7820e2..e80b59ac1e 100644
--- a/testing/mozbase/mozprocess/mozprocess/processhandler.py
+++ b/testing/mozbase/mozprocess/mozprocess/processhandler.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 import os
 import signal
@@ -11,7 +10,7 @@ import sys
 import threading
 import time
 import traceback
-from Queue import Queue, Empty
+from queue import Queue, Empty
 from datetime import datetime
 
 __all__ = ['ProcessHandlerMixin', 'ProcessHandler', 'LogOutput',
@@ -112,7 +111,7 @@ class ProcessHandlerMixin(object):
                                           shell, cwd, env,
                                           universal_newlines, startupinfo, creationflags)
             except OSError:
-                print >> sys.stderr, args
+                print(args, file=sys.stderr)
                 raise
 
         def debug(self, msg):
@@ -121,14 +120,14 @@ class ProcessHandlerMixin(object):
             thread = threading.current_thread().name
             print("DBG::MOZPROC PID:{} ({}) | {}".format(self.pid, thread, msg))
 
-        def __del__(self, _maxint=sys.maxint):
+        def __del__(self, _maxint=sys.maxsize):
             if isWin:
                 handle = getattr(self, '_handle', None)
                 if handle:
                     if hasattr(self, '_internal_poll'):
                         self._internal_poll(_deadstate=_maxint)
                     else:
-                        self.poll(_deadstate=sys.maxint)
+                        self.poll(_deadstate=sys.maxsize)
                 if handle or self._job or self._io_port:
                     self._cleanup()
             else:
@@ -161,7 +160,7 @@ class ProcessHandlerMixin(object):
                             # application might already have been terminated itself. Any other
                             # error would indicate a problem in killing the process.
                             if getattr(e, "errno", None) != 3:
-                                print >> sys.stderr, "Could not terminate process: %s" % self.pid
+                                print("Could not terminate process: %s" % self.pid, file=sys.stderr)
                                 raise
                     else:
                         os.kill(pid, sig)
@@ -196,7 +195,7 @@ class ProcessHandlerMixin(object):
 
             return subprocess.Popen.poll(self)
 
-        def wait(self):
+        def wait(self, timeout=None):
             """ Popen.wait
                 Called to wait for a running process to shut down and return
                 its exit code
@@ -228,7 +227,7 @@ class ProcessHandlerMixin(object):
                      p2cread, p2cwrite,
                      c2pread, c2pwrite,
                      errread, errwrite) = args_tuple
-                if not isinstance(args, basestring):
+                if not isinstance(args, str):
                     args = subprocess.list2cmdline(args)
 
                 # Always or in the create new process group
@@ -256,8 +255,7 @@ class ProcessHandlerMixin(object):
                 if not (can_create_job or can_nest_jobs) and not self._ignore_children:
                     # We can't create job objects AND the user wanted us to
                     # Warn the user about this.
-                    print >> sys.stderr, \
-                        "ProcessManager UNABLE to use job objects to manage child processes"
+                    print("ProcessManager UNABLE to use job objects to manage child processes", file=sys.stderr)
 
                 # set process creation flags
                 creationflags |= winprocess.CREATE_SUSPENDED
@@ -267,7 +265,7 @@ class ProcessHandlerMixin(object):
                 if not (can_create_job or can_nest_jobs):
                     # Since we've warned, we just log info here to inform you
                     # of the consequence of setting ignore_children = True
-                    print "ProcessManager NOT managing child processes"
+                    print("ProcessManager NOT managing child processes")
 
                 # create the process
                 hp, ht, pid, tid = winprocess.CreateProcess(
@@ -340,10 +338,10 @@ class ProcessHandlerMixin(object):
                         # Spin up our thread for managing the IO Completion Port
                         self._procmgrthread = threading.Thread(target=self._procmgr)
                     except:
-                        print >> sys.stderr, """Exception trying to use job objects;
-falling back to not using job objects for managing child processes"""
+                        print("""Exception trying to use job objects;
+falling back to not using job objects for managing child processes""", file=sys.stderr)
                         tb = traceback.format_exc()
-                        print >> sys.stderr, tb
+                        print(tb, file=sys.stderr)
                         # Ensure no dangling handles left behind
                         self._cleanup_job_io_port()
                 else:
@@ -406,14 +404,10 @@ falling back to not using job objects for managing child processes"""
                         # don't want to mistake that situation for the situation of an unexpected
                         # parent abort (which is what we're looking for here).
                         if diff.seconds > self.MAX_IOCOMPLETION_PORT_NOTIFICATION_DELAY:
-                            print >> sys.stderr, \
-                                "WARNING | IO Completion Port failed to signal process shutdown"
-                            print >> sys.stderr, \
-                                "Parent process %s exited with children alive:" % self.pid
-                            print >> sys.stderr, \
-                                "PIDS: %s" % ', '.join([str(i) for i in self._spawned_procs])
-                            print >> sys.stderr, \
-                                "Attempting to kill them, but no guarantee of success"
+                            print("WARNING | IO Completion Port failed to signal process shutdown", file=sys.stderr)
+                            print("Parent process %s exited with children alive:" % self.pid, file=sys.stderr)
+                            print("PIDS: %s" % ', '.join([str(i) for i in self._spawned_procs]), file=sys.stderr)
+                            print("Attempting to kill them, but no guarantee of success", file=sys.stderr)
 
                             self.kill()
                             self._process_events.put({self.pid: 'FINISHED'})
@@ -424,16 +418,15 @@ falling back to not using job objects for managing child processes"""
                         errcode = winprocess.GetLastError()
                         if errcode == winprocess.ERROR_ABANDONED_WAIT_0:
                             # Then something has killed the port, break the loop
-                            print >> sys.stderr, "IO Completion Port unexpectedly closed"
+                            print("IO Completion Port unexpectedly closed", file=sys.stderr)
                             self._process_events.put({self.pid: 'FINISHED'})
                             break
                         elif errcode == winprocess.WAIT_TIMEOUT:
                             # Timeouts are expected, just keep on polling
                             continue
                         else:
-                            print >> sys.stderr, \
-                                "Error Code %s trying to query IO Completion Port, " \
-                                "exiting" % errcode
+                            print("Error Code %s trying to query IO Completion Port, "
+                                "exiting" % errcode, file=sys.stderr)
                             raise WinError(errcode)
                             break
 
@@ -480,7 +473,7 @@ falling back to not using job objects for managing child processes"""
                             self.debug("We got a message %s" % msgid.value)
                             pass
 
-            def _wait(self):
+            def _wait(self, timeout=None):
                 # First, check to see if the process is still running
                 if self._handle:
                     self.returncode = winprocess.GetExitCodeProcess(self._handle)
@@ -534,11 +527,11 @@ falling back to not using job objects for managing child processes"""
 
                     if rc == winprocess.WAIT_TIMEOUT:
                         # The process isn't dead, so kill it
-                        print "Timed out waiting for process to close, attempting TerminateProcess"
+                        print("Timed out waiting for process to close, attempting TerminateProcess")
                         self.kill()
                     elif rc == winprocess.WAIT_OBJECT_0:
                         # We caught WAIT_OBJECT_0, which indicates all is well
-                        print "Single process terminated successfully"
+                        print("Single process terminated successfully")
                         self.returncode = winprocess.GetExitCodeProcess(self._handle)
                     else:
                         # An error occured we should probably throw
@@ -589,7 +582,7 @@ falling back to not using job objects for managing child processes"""
 
         elif isPosix:
 
-            def _wait(self):
+            def _wait(self, timeout=None):
                 """ Haven't found any reason to differentiate between these platforms
                     so they all use the same wait callback.  If it is necessary to
                     craft different styles of wait, then a new _wait method
@@ -616,15 +609,23 @@ falling back to not using job objects for managing child processes"""
                         if getattr(e, "errno", None) != 10:
                             # Error 10 is "no child process", which could indicate normal
                             # close
-                            print >> sys.stderr, \
-                                "Encountered error waiting for pid to close: %s" % e
+                            print("Encountered error waiting for pid to close: %s" % e, file=sys.stderr)
                             raise
 
                         return self.returncode
 
                 else:
-                    # For non-group wait, call base class
-                    subprocess.Popen.wait(self)
+                    # For non-group wait, use os.waitpid directly to avoid
+                    # infinite recursion with Python 3.13's Popen.wait()
+                    if self.returncode is None:
+                        try:
+                            pid, sts = os.waitpid(self.pid, 0)
+                            if os.WIFSIGNALED(sts):
+                                self.returncode = -os.WTERMSIG(sts)
+                            elif os.WIFEXITED(sts):
+                                self.returncode = os.WEXITSTATUS(sts)
+                        except OSError:
+                            pass
                     return self.returncode
 
             def _cleanup(self):
@@ -632,11 +633,20 @@ falling back to not using job objects for managing child processes"""
 
         else:
             # An unrecognized platform, we will call the base class for everything
-            print >> sys.stderr, \
-                "Unrecognized platform, process groups may not be managed properly"
+            print("Unrecognized platform, process groups may not be managed properly", file=sys.stderr)
 
-            def _wait(self):
-                self.returncode = subprocess.Popen.wait(self)
+            def _wait(self, timeout=None):
+                # Use os.waitpid directly to avoid infinite recursion
+                # with Python 3.13's Popen.wait() which calls self._wait()
+                if self.returncode is None:
+                    try:
+                        pid, sts = os.waitpid(self.pid, 0)
+                        if os.WIFSIGNALED(sts):
+                            self.returncode = -os.WTERMSIG(sts)
+                        elif os.WIFEXITED(sts):
+                            self.returncode = os.WEXITSTATUS(sts)
+                    except OSError:
+                        pass
                 return self.returncode
 
             def _cleanup(self):
@@ -842,8 +852,8 @@ falling back to not using job objects for managing child processes"""
 
     # TODO Remove this method when consumers have been fixed
     def waitForFinish(self, timeout=None):
-        print >> sys.stderr, "MOZPROCESS WARNING: ProcessHandler.waitForFinish() is deprecated, " \
-                             "use ProcessHandler.wait() instead"
+        print("MOZPROCESS WARNING: ProcessHandler.waitForFinish() is deprecated, "
+            "use ProcessHandler.wait() instead", file=sys.stderr)
         return self.wait(timeout=timeout)
 
     @property
@@ -874,10 +884,9 @@ falling back to not using job objects for managing child processes"""
 
             if new_pgid and new_pgid != self.proc.pgid:
                 self.proc.detached_pid = new_pid
-                print >> sys.stdout, \
-                    'Child process with id "%s" has been marked as detached because it is no ' \
-                    'longer in the managed process group. Keeping reference to the process id ' \
-                    '"%s" which is the new child process.' % (self.pid, new_pid)
+                print('Child process with id "%s" has been marked as detached because it is no '
+                    'longer in the managed process group. Keeping reference to the process id '
+                    '"%s" which is the new child process.' % (self.pid, new_pid), file=sys.stdout)
 
 
 class CallableList(list):
@@ -966,14 +975,20 @@ class ProcessReader(object):
             else:
                 if output_timeout is not None:
                     output_timeout = now + self.output_timeout
-                callback(line.rstrip())
+                _l = line.rstrip()
+                if isinstance(_l, bytes):
+                    _l = _l.decode('utf-8', errors='replace')
+                callback(_l)
             if timeout is not None and now > timeout:
                 timed_out = True
                 break
         # process remaining lines to read
         while not queue.empty():
             line, callback = queue.get(False)
-            callback(line.rstrip())
+            _l = line.rstrip()
+            if isinstance(_l, bytes):
+                _l = _l.decode('utf-8', errors='replace')
+            callback(_l)
         if timed_out:
             self.timeout_callback()
         if stdout_reader:
diff --git a/testing/mozbase/mozprocess/mozprocess/qijo.py b/testing/mozbase/mozprocess/mozprocess/qijo.py
index ce23909fa5..2b006b1183 100644
--- a/testing/mozbase/mozprocess/mozprocess/qijo.py
+++ b/testing/mozbase/mozprocess/mozprocess/qijo.py
@@ -2,7 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import absolute_import
 
 from ctypes import (
     c_void_p,
@@ -87,7 +86,7 @@ JobObjectBasicAndIoAccountingInformation = 8
 JobObjectExtendedLimitInformation = 9
 
 
-class JobObjectInfo(object):
+class JobObjectInfo:
     mapping = {'JobObjectBasicAndIoAccountingInformation': 8,
                'JobObjectExtendedLimitInformation': 9,
                'JobObjectAssociateCompletionPortInformation': 7}
@@ -98,12 +97,12 @@ class JobObjectInfo(object):
     }
 
     def __init__(self, _class):
-        if isinstance(_class, basestring):
+        if isinstance(_class, str):
             assert _class in self.mapping, \
-                'Class should be one of %s; you gave %s' % (self.mapping, _class)
+                'Class should be one of {}; you gave {}'.format(self.mapping, _class)
             _class = self.mapping[_class]
         assert _class in self.structures, \
-            'Class should be one of %s; you gave %s' % (self.structures, _class)
+            'Class should be one of {}; you gave {}'.format(self.structures, _class)
         self.code = _class
         self.info = self.structures[_class]()
 
@@ -131,7 +130,7 @@ _QueryInformationJobObject = QueryInformationJobObjectProto(
 )
 
 
-class SubscriptableReadOnlyStruct(object):
+class SubscriptableReadOnlyStruct:
 
     def __init__(self, struct):
         self._struct = struct
diff --git a/testing/mozbase/mozprocess/mozprocess/winprocess.py b/testing/mozbase/mozprocess/mozprocess/winprocess.py
index b748f8f302..50de744463 100644
--- a/testing/mozbase/mozprocess/mozprocess/winprocess.py
+++ b/testing/mozbase/mozprocess/mozprocess/winprocess.py
@@ -447,33 +447,33 @@ def CanCreateJobObject():
 
 
 def parent():
-    print 'Starting parent'
+    print('Starting parent')
     currentProc = GetCurrentProcess()
     if IsProcessInJob(currentProc):
-        print >> sys.stderr, "You should not be in a job object to test"
+        print("You should not be in a job object to test", file=sys.stderr)
         sys.exit(1)
     assert CanCreateJobObject()
-    print 'File: %s' % __file__
+    print('File: %s' % __file__)
     command = [sys.executable, __file__, '-child']
-    print 'Running command: %s' % command
+    print('Running command: %s' % command)
     process = subprocess.Popen(command)
     process.kill()
     code = process.returncode
-    print 'Child code: %s' % code
+    print('Child code: %s' % code)
     assert code == 127
 
 
 def child():
-    print 'Starting child'
+    print('Starting child')
     currentProc = GetCurrentProcess()
     injob = IsProcessInJob(currentProc)
-    print "Is in a job?: %s" % injob
+    print("Is in a job?: %s" % injob)
     can_create = CanCreateJobObject()
-    print 'Can create job?: %s' % can_create
+    print('Can create job?: %s' % can_create)
     process = subprocess.Popen('c:\\windows\\notepad.exe')
     assert process._job
     jobinfo = QueryInformationJobObject(process._job, 'JobObjectExtendedLimitInformation')
-    print 'Job info: %s' % jobinfo
+    print('Job info: %s' % jobinfo)
     limitflags = jobinfo['BasicLimitInformation']['LimitFlags']
-    print 'LimitFlags: %s' % limitflags
+    print('LimitFlags: %s' % limitflags)
     process.kill()
diff --git a/testing/mozbase/mozprocess/tests/proccountfive.py b/testing/mozbase/mozprocess/tests/proccountfive.py
index 5ec74b32ab..c2c5b0751c 100644
--- a/testing/mozbase/mozprocess/tests/proccountfive.py
+++ b/testing/mozbase/mozprocess/tests/proccountfive.py
@@ -1,2 +1,3 @@
+from __future__ import print_function
 for i in range(0, 5):
-    print i
+    print(i)
diff --git a/testing/mozbase/mozprocess/tests/proclaunch.py b/testing/mozbase/mozprocess/tests/proclaunch.py
index ad06a23a16..926440b22f 100644
--- a/testing/mozbase/mozprocess/tests/proclaunch.py
+++ b/testing/mozbase/mozprocess/tests/proclaunch.py
@@ -159,7 +159,7 @@ class ProcessLauncher(object):
 
         maxtime = self.children[proc_name].maxtime
         if self.verbose:
-            print "%sLaunching %s for %d*%d seconds" % (" " * level,
+            print("%sLaunching %s for %d*%d seconds" % (" " * level,)
                                                         proc_name,
                                                         maxtime,
                                                         self.UNIT_TIME)
@@ -174,7 +174,7 @@ class ProcessLauncher(object):
 
         self._launch(maxtime)
         if self.verbose:
-            print "%sFinished %s" % (" " * level, proc_name)
+            print("%sFinished %s" % (" " * level, proc_name))
 
     def _launch(self, running_time):
         """
diff --git a/testing/mozbase/mozprocess/tests/procnonewline.py b/testing/mozbase/mozprocess/tests/procnonewline.py
index 428a02bcb5..75a7a00ed7 100644
--- a/testing/mozbase/mozprocess/tests/procnonewline.py
+++ b/testing/mozbase/mozprocess/tests/procnonewline.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import sys
-print "this is a newline"
+print("this is a newline")
 sys.stdout.write("this has NO newline")
diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess.py b/testing/mozbase/mozprocess/tests/test_mozprocess.py
index bf8ba194c2..eb80c69b81 100644
--- a/testing/mozbase/mozprocess/tests/test_mozprocess.py
+++ b/testing/mozbase/mozprocess/tests/test_mozprocess.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import subprocess
 import sys
@@ -42,9 +43,9 @@ def make_proclaunch(aDir):
         stdout, stderr = process.communicate()
         if process.returncode:
             # SomethingBadHappen; print all the things
-            print "%s: exit %d" % (command, process.returncode)
-            print "stdout:\n%s" % stdout
-            print "stderr:\n%s" % stderr
+            print(("%s: exit %d" % (command, process.returncode)))
+            print(("stdout:\n%s" % stdout))
+            print(("stderr:\n%s" % stderr))
             raise subprocess.CalledProcessError(process.returncode, command, stdout)
 
     # ensure the launcher now exists
@@ -110,7 +111,7 @@ class ProcTest(proctest.ProcTest):
             processhandler.ProcessHandler([self.proclaunch, "process_normal_finish.ini"],
                                           args=["1", "2", "3"],
                                           cwd=here)
-        except TypeError, e:
+        except TypeError as e:
             err = e
 
         self.assertTrue(err)
@@ -128,7 +129,7 @@ class ProcTest(proctest.ProcTest):
             processhandler.ProcessHandler([self.proclaunch, "process_normal_finish.ini"],
                                           args=["1", "2", "3"],
                                           cwd=here)
-        except TypeError, e:
+        except TypeError as e:
             err = e
 
         self.assertTrue(err)
diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py b/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py
index 36dbc95cc5..cd0c0c2173 100644
--- a/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py
+++ b/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py
@@ -74,7 +74,7 @@ class ProcTestKill(proctest.ProcTest):
         p.run()
         p.kill()
 
-        self.assertEquals(p.proc.returncode, -signal.SIGTERM)
+        self.assertEqual(p.proc.returncode, -signal.SIGTERM)
 
     @unittest.skipUnless(processhandler.isPosix, "posix only")
     def test_process_kill_with_sigint_if_needed(self):
@@ -85,7 +85,7 @@ class ProcTestKill(proctest.ProcTest):
         time.sleep(1)
         p.kill()
 
-        self.assertEquals(p.proc.returncode, -signal.SIGKILL)
+        self.assertEqual(p.proc.returncode, -signal.SIGKILL)
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess_misc.py b/testing/mozbase/mozprocess/tests/test_mozprocess_misc.py
index 7a7c690d13..d375836610 100644
--- a/testing/mozbase/mozprocess/tests/test_mozprocess_misc.py
+++ b/testing/mozbase/mozprocess/tests/test_mozprocess_misc.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 
 import os
 import unittest
diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess_output.py b/testing/mozbase/mozprocess/tests/test_mozprocess_output.py
index e9ad266209..107bbbef87 100644
--- a/testing/mozbase/mozprocess/tests/test_mozprocess_output.py
+++ b/testing/mozbase/mozprocess/tests/test_mozprocess_output.py
@@ -44,7 +44,7 @@ class ProcTestOutput(proctest.ProcTest):
             stream.write(str(i) + '\n')
 
         buf.flush()
-        self.assertEquals(stream.getvalue().strip(), expected)
+        self.assertEqual(stream.getvalue().strip(), expected)
 
         # make sure mozprocess doesn't close the stream
         # since mozprocess didn't create it
diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess_params.py b/testing/mozbase/mozprocess/tests/test_mozprocess_params.py
index d4d1f00f36..6c1cf1daef 100644
--- a/testing/mozbase/mozprocess/tests/test_mozprocess_params.py
+++ b/testing/mozbase/mozprocess/tests/test_mozprocess_params.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import unittest
 from mozprocess import processhandler
 
@@ -13,7 +14,7 @@ class ParamTests(unittest.TestCase):
     def test_process_outputline_handler(self):
         """Parameter processOutputLine is accepted with a single function"""
         def output(line):
-            print("output " + str(line))
+            print(("output " + str(line)))
         err = None
         try:
             processhandler.ProcessHandler(['ls', '-l'], processOutputLine=output)
@@ -24,7 +25,7 @@ class ParamTests(unittest.TestCase):
     def test_process_outputline_handler_list(self):
         """Parameter processOutputLine is accepted with a list of functions"""
         def output(line):
-            print("output " + str(line))
+            print(("output " + str(line)))
         err = None
         try:
             processhandler.ProcessHandler(['ls', '-l'], processOutputLine=[output])
diff --git a/testing/mozbase/mozprofile/mozprofile/__init__.py b/testing/mozbase/mozprofile/mozprofile/__init__.py
index 96bf1020bc..7416820652 100644
--- a/testing/mozbase/mozprofile/mozprofile/__init__.py
+++ b/testing/mozbase/mozprofile/mozprofile/__init__.py
@@ -11,11 +11,11 @@ subclasses ``FirefoxProfile`` and ``ThundebirdProfile`` are available
 with preset preferences for those applications.
 """
 
-from addons import *
-from cli import *
-from diff import *
-from permissions import *
-from prefs import *
-from profile import *
-from view import *
-from webapps import *
+from .addons import *
+from .cli import *
+from .diff import *
+from .permissions import *
+from .prefs import *
+from .profile import *
+from .view import *
+from .webapps import *
diff --git a/testing/mozbase/mozprofile/mozprofile/addons.py b/testing/mozbase/mozprofile/mozprofile/addons.py
index e96fd6b36c..4122579f04 100644
--- a/testing/mozbase/mozprofile/mozprofile/addons.py
+++ b/testing/mozbase/mozprofile/mozprofile/addons.py
@@ -6,12 +6,13 @@ import os
 import shutil
 import sys
 import tempfile
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import zipfile
 from xml.dom import minidom
 
 import mozfile
 from mozlog.unstructured import getLogger
+import six
 
 # Needed for the AMO's rest API -
 # https://developer.mozilla.org/en/addons.mozilla.org_%28AMO%29_API_Developers%27_Guide/The_generic_AMO_API
@@ -104,7 +105,7 @@ class AddonManager(object):
         :param target_folder: Folder to store the XPI file in
 
         """
-        response = urllib2.urlopen(url)
+        response = six.moves.urllib.request.urlopen(url)
         fd, path = tempfile.mkstemp(suffix='.xpi')
         os.write(fd, response.read())
         os.close(fd)
@@ -168,14 +169,14 @@ class AddonManager(object):
 
         # install addon paths
         if addons:
-            if isinstance(addons, basestring):
+            if isinstance(addons, str):
                 addons = [addons]
             for addon in set(addons):
                 self.install_from_path(addon)
 
         # install addon manifests
         if manifests:
-            if isinstance(manifests, basestring):
+            if isinstance(manifests, str):
                 manifests = [manifests]
             for manifest in manifests:
                 self.install_from_manifest(manifest)
@@ -226,7 +227,7 @@ class AddonManager(object):
 
         .. _query-documentation: https://developer.mozilla.org/en/addons.mozilla.org_%28AMO%29_API_Developers%27_Guide/The_generic_AMO_API # noqa
         """
-        response = urllib2.urlopen(query)
+        response = six.moves.urllib.request.urlopen(query)
         dom = minidom.parseString(response.read())
         for node in dom.getElementsByTagName('install')[0].childNodes:
             if node.nodeType == node.TEXT_NODE:
@@ -291,7 +292,7 @@ class AddonManager(object):
             else:
                 raise IOError('Add-on path is neither an XPI nor a directory: %s' % addon_path)
         except (IOError, KeyError) as e:
-            raise AddonFormatError(str(e)), None, sys.exc_info()[2]
+            six.reraise(AddonFormatError(str(e)), None, sys.exc_info()[2])
 
         try:
             doc = minidom.parseString(manifest)
@@ -304,18 +305,18 @@ class AddonManager(object):
             for entry, value in description.attributes.items():
                 # Remove the namespace prefix from the tag for comparison
                 entry = entry.replace(em, "")
-                if entry in details.keys():
+                if entry in list(details.keys()):
                     details.update({entry: value})
             for node in description.childNodes:
                 # Remove the namespace prefix from the tag for comparison
                 entry = node.nodeName.replace(em, "")
-                if entry in details.keys():
+                if entry in list(details.keys()):
                     details.update({entry: get_text(node)})
         except Exception as e:
-            raise AddonFormatError(str(e)), None, sys.exc_info()[2]
+            six.reraise(AddonFormatError(str(e)), None, sys.exc_info()[2])
 
         # turn unpack into a true/false value
-        if isinstance(details['unpack'], basestring):
+        if isinstance(details['unpack'], str):
             details['unpack'] = details['unpack'].lower() == 'true'
 
         # If no ID is set, the add-on is invalid
diff --git a/testing/mozbase/mozprofile/mozprofile/cli.py b/testing/mozbase/mozprofile/mozprofile/cli.py
index 1dd513e561..5b265241b8 100755
--- a/testing/mozbase/mozprofile/mozprofile/cli.py
+++ b/testing/mozbase/mozprofile/mozprofile/cli.py
@@ -11,11 +11,12 @@ If no profile is specified, a new profile is created and the path of the
 resulting profile is printed.
 """
 
+from __future__ import print_function
 import sys
 from optparse import OptionParser
-from prefs import Preferences
-from profile import FirefoxProfile
-from profile import Profile
+from .prefs import Preferences
+from .profile import FirefoxProfile
+from .profile import Profile
 
 __all__ = ['MozProfileCLI', 'cli']
 
@@ -120,12 +121,12 @@ def cli(args=sys.argv[1:]):
 
     if cli.options.view:
         # view the profile, if specified
-        print profile.summary()
+        print(profile.summary())
         return
 
     # if no profile was passed in print the newly created profile
     if not cli.options.profile:
-        print profile.profile
+        print(profile.profile)
 
 if __name__ == '__main__':
     cli()
diff --git a/testing/mozbase/mozprofile/mozprofile/diff.py b/testing/mozbase/mozprofile/mozprofile/diff.py
index 98776e838c..c2fb0ef88e 100644
--- a/testing/mozbase/mozprofile/mozprofile/diff.py
+++ b/testing/mozbase/mozprofile/mozprofile/diff.py
@@ -4,8 +4,9 @@
 diff two profile summaries
 """
 
+from __future__ import print_function
 import difflib
-import profile
+from . import profile
 import optparse
 import os
 import sys
@@ -72,10 +73,10 @@ def diff_profiles(args=sys.argv[1:]):
     # display them
     while diffs:
         key, value = diffs.pop(0)
-        print '[%s]:\n' % key
-        print value
+        print('[%s]:\n' % key)
+        print(value)
         if diffs:
-            print '-' * 4
+            print('-' * 4)
 
 if __name__ == '__main__':
     diff_profiles()
diff --git a/testing/mozbase/mozprofile/mozprofile/permissions.py b/testing/mozbase/mozprofile/mozprofile/permissions.py
index ea13d96f02..b9e7769637 100644
--- a/testing/mozbase/mozprofile/mozprofile/permissions.py
+++ b/testing/mozbase/mozprofile/mozprofile/permissions.py
@@ -10,7 +10,8 @@ add permissions to the profile
 import codecs
 import os
 import sqlite3
-import urlparse
+import six.moves.urllib.parse
+import six
 
 __all__ = ['MissingPrimaryLocationError', 'MultiplePrimaryLocationsError',
            'DEFAULT_PORTS', 'DuplicateLocationError', 'BadPortLocationError',
@@ -78,7 +79,7 @@ class LocationsSyntaxError(Exception):
         return s
 
 
-class Location(object):
+class Location:
     """Represents a location line in server-locations.txt."""
 
     attrs = ('scheme', 'host', 'port')
@@ -100,13 +101,13 @@ class Location(object):
     __eq__ = isEqual
 
     def url(self):
-        return '%s://%s:%s' % (self.scheme, self.host, self.port)
+        return '{}://{}:{}'.format(self.scheme, self.host, self.port)
 
     def __str__(self):
-        return '%s  %s' % (self.url(), ','.join(self.options))
+        return '{}  {}'.format(self.url(), ','.join(self.options))
 
 
-class ServerLocations(object):
+class ServerLocations:
     """Iterable collection of locations.
     Use provided functions to add new locations, rather that manipulating
     _locations directly, in order to check for errors and to ensure the
@@ -137,7 +138,7 @@ class ServerLocations(object):
             self.add_callback([location])
 
     def add_host(self, host, port='80', scheme='http', options='privileged'):
-        if isinstance(options, basestring):
+        if isinstance(options, str):
             options = options.split(',')
         self.add(Location(scheme, host, port, options))
 
@@ -180,7 +181,7 @@ class ServerLocations(object):
             # parse the server url
             if '://' not in server:
                 server = 'http://' + server
-            scheme, netloc, path, query, fragment = urlparse.urlsplit(server)
+            scheme, netloc, path, query, fragment = six.moves.urllib.parse.urlsplit(server)
             # get the host and port
             try:
                 host, port = netloc.rsplit(':', 1)
@@ -205,7 +206,7 @@ class ServerLocations(object):
             self.add_callback(new_locations)
 
 
-class Permissions(object):
+class Permissions:
     """Allows handling of permissions for ``mozprofile``"""
 
     def __init__(self, profileDir, locations=None):
@@ -267,7 +268,7 @@ class Permissions(object):
         for location in locations:
             # set the permissions
             permissions = {'allowXULXBL': 'noxul' not in location.options}
-            for perm, allow in permissions.iteritems():
+            for perm, allow in permissions.items():
                 if allow:
                     permission_type = 1
                 else:
diff --git a/testing/mozbase/mozprofile/mozprofile/prefs.py b/testing/mozbase/mozprofile/mozprofile/prefs.py
index b0eb01e280..4b0cc9c251 100644
--- a/testing/mozbase/mozprofile/mozprofile/prefs.py
+++ b/testing/mozbase/mozprofile/mozprofile/prefs.py
@@ -6,11 +6,12 @@
 user preferences
 """
 
+from __future__ import print_function
 import json
 import mozfile
 import os
 import tokenize
-from ConfigParser import SafeConfigParser as ConfigParser
+from configparser import ConfigParser
 from StringIO import StringIO
 
 __all__ = ('PreferencesReadError', 'Preferences')
@@ -35,7 +36,7 @@ class Preferences(object):
         """
         # wants a list of 2-tuples
         if isinstance(prefs, dict):
-            prefs = prefs.items()
+            prefs = list(prefs.items())
         if cast:
             prefs = [(i, self.cast(j)) for i, j in prefs]
         self._prefs += prefs
@@ -63,7 +64,7 @@ class Preferences(object):
           with the ''s removed from both sides
         """
 
-        if not isinstance(value, basestring):
+        if not isinstance(value, str):
             return value  # no op
         quote = "'"
         if value == 'true':
@@ -124,7 +125,7 @@ class Preferences(object):
                 raise PreferencesReadError("No section '%s' in %s" % (section, path))
             retval = parser.items(section, raw=True)
         else:
-            retval = parser.defaults().items()
+            retval = list(parser.defaults().items())
 
         # cast the preferences since .ini is just strings
         return [(i, cls.cast(j)) for i, j in retval]
@@ -142,10 +143,10 @@ class Preferences(object):
                 raise PreferencesReadError("Malformed preferences: %s" % path)
             values = [i[1] for i in prefs]
         elif isinstance(prefs, dict):
-            values = prefs.values()
+            values = list(prefs.values())
         else:
             raise PreferencesReadError("Malformed preferences: %s" % path)
-        types = (bool, basestring, int)
+        types = (bool, str, int)
         if [i for i in values if not [isinstance(i, j) for j in types]]:
             raise PreferencesReadError("Only bool, string, and int values allowed")
         return prefs
@@ -185,7 +186,7 @@ class Preferences(object):
         retval = []
 
         def pref(a, b):
-            if interpolation and isinstance(b, basestring):
+            if interpolation and isinstance(b, str):
                 b = b.format(**interpolation)
             retval.append((a, b))
         lines = [i.strip().rstrip(';') for i in string.split('\n') if i.strip()]
@@ -196,12 +197,12 @@ class Preferences(object):
             try:
                 eval(line, _globals, {})
             except SyntaxError:
-                print line
+                print(line)
                 raise
 
         # de-magic the marker
         for index, (key, value) in enumerate(retval):
-            if isinstance(value, basestring) and marker in value:
+            if isinstance(value, str) and marker in value:
                 retval[index] = (key, value.replace(marker, '//'))
 
         return retval
@@ -210,14 +211,14 @@ class Preferences(object):
     def write(cls, _file, prefs, pref_string='user_pref(%s, %s);'):
         """write preferences to a file"""
 
-        if isinstance(_file, basestring):
-            f = file(_file, 'a')
+        if isinstance(_file, str):
+            f = open(_file, 'a')
         else:
             f = _file
 
         if isinstance(prefs, dict):
             # order doesn't matter
-            prefs = prefs.items()
+            prefs = list(prefs.items())
 
         # serialize -> JSON
         _prefs = [(json.dumps(k), json.dumps(v))
@@ -225,8 +226,8 @@ class Preferences(object):
 
         # write the preferences
         for _pref in _prefs:
-            print >> f, pref_string % _pref
+            print(pref_string % _pref, file=f)
 
         # close the file if opened internally
-        if isinstance(_file, basestring):
+        if isinstance(_file, str):
             f.close()
diff --git a/testing/mozbase/mozprofile/mozprofile/profile.py b/testing/mozbase/mozprofile/mozprofile/profile.py
index b07b114492..21c75f5dc0 100644
--- a/testing/mozbase/mozprofile/mozprofile/profile.py
+++ b/testing/mozbase/mozprofile/mozprofile/profile.py
@@ -7,12 +7,12 @@ import time
 import tempfile
 import uuid
 
-from addons import AddonManager
+from .addons import AddonManager
 import mozfile
-from permissions import Permissions
-from prefs import Preferences
+from .permissions import Permissions
+from .prefs import Preferences
 from shutil import copytree
-from webapps import WebappCollection
+from .webapps import WebappCollection
 
 __all__ = ['Profile',
            'FirefoxProfile',
@@ -20,7 +20,7 @@ __all__ = ['Profile',
            'ThunderbirdProfile']
 
 
-class Profile(object):
+class Profile:
     """Handles all operations regarding profile.
 
     Creating new profiles, installing add-ons, setting preferences and
@@ -30,7 +30,7 @@ class Profile(object):
     the object is garbage collected: ::
 
       profile = Profile()
-      print profile.profile  # this is the path to the created profile
+      print(profile.profile)  # this is the path to the created profile
       del profile
       # the profile path has been removed from disk
 
@@ -66,7 +66,7 @@ class Profile(object):
         if preferences:
             if isinstance(preferences, dict):
                 # unordered
-                preferences = preferences.items()
+                preferences = list(preferences.items())
 
             # sanity check
             assert not [i for i in preferences if len(i) != 2]
@@ -97,7 +97,7 @@ class Profile(object):
         self.written_prefs = set()
 
         # Our magic markers
-        nonce = '%s %s' % (str(time.time()), uuid.uuid4())
+        nonce = '{} {}'.format(str(time.time()), uuid.uuid4())
         self.delimeters = ('#MozRunner Prefs Start %s' % nonce,
                            '#MozRunner Prefs End %s' % nonce)
 
@@ -220,7 +220,7 @@ class Profile(object):
 
         # this is a dict sometimes, convert
         if isinstance(preferences, dict):
-            preferences = preferences.items()
+            preferences = list(preferences.items())
 
         # add new prefs to preserve them during reset
         for new_pref in preferences:
@@ -238,7 +238,7 @@ class Profile(object):
         """
 
         path = os.path.join(self.profile, filename)
-        with file(path) as f:
+        with open(path) as f:
             lines = f.read().splitlines()
 
         def last_index(_list, value):
@@ -246,7 +246,7 @@ class Profile(object):
             returns the last index of an item;
             this should actually be part of python code but it isn't
             """
-            for index in reversed(range(len(_list))):
+            for index in reversed(list(range(len(_list)))):
                 if _list[index] == value:
                     return index
         s = last_index(lines, self.delimeters[0])
@@ -254,18 +254,18 @@ class Profile(object):
 
         # ensure both markers are found
         if s is None:
-            assert e is None, '%s found without %s' % (self.delimeters[1], self.delimeters[0])
+            assert e is None, '{} found without {}'.format(self.delimeters[1], self.delimeters[0])
             return False  # no preferences found
         elif e is None:
-            assert s is None, '%s found without %s' % (self.delimeters[0], self.delimeters[1])
+            assert s is None, '{} found without {}'.format(self.delimeters[0], self.delimeters[1])
 
         # ensure the markers are in the proper order
-        assert e > s, '%s found at %s, while %s found at %s' % (self.delimeters[1], e,
+        assert e > s, '{} found at {}, while {} found at {}'.format(self.delimeters[1], e,
                                                                 self.delimeters[0], s)
 
         # write the prefs
         cleaned_prefs = '\n'.join(lines[:s] + lines[e + 1:])
-        with file(path, 'w') as f:
+        with open(path, 'w') as f:
             f.write(cleaned_prefs)
         return True
 
@@ -311,7 +311,7 @@ class Profile(object):
                     prefs = dict(prefs)
                     parts.append((prefs_file,
                                   '\n%s' % ('\n'.join(
-                                      ['%s: %s' % (key, format_value(key, prefs[key]))
+                                      ['{}: {}'.format(key, format_value(key, prefs[key]))
                                        for key in sorted(prefs.keys())]))))
 
                     # Currently hardcorded to 'network.proxy.autoconfig_url'
@@ -340,7 +340,7 @@ class Profile(object):
         if return_parts:
             return parts
 
-        retval = '%s\n' % ('\n\n'.join(['[%s]: %s' % (key, value)
+        retval = '%s\n' % ('\n\n'.join(['[{}]: {}'.format(key, value)
                                         for key, value in parts]))
         return retval
 
diff --git a/testing/mozbase/mozprofile/mozprofile/view.py b/testing/mozbase/mozprofile/mozprofile/view.py
index fcab85b0a8..fb427b510d 100644
--- a/testing/mozbase/mozprofile/mozprofile/view.py
+++ b/testing/mozbase/mozprofile/mozprofile/view.py
@@ -4,6 +4,7 @@
 script to view mozilla profiles
 """
 
+from __future__ import print_function
 import mozprofile
 import optparse
 import os
@@ -35,9 +36,9 @@ def view_profile(args=sys.argv[1:]):
     while args:
         path = args.pop(0)
         profile = mozprofile.Profile(path)
-        print profile.summary()
+        print(profile.summary())
         if args:
-            print '-' * 4
+            print('-' * 4)
 
 if __name__ == '__main__':
     view_profile()
diff --git a/testing/mozbase/mozprofile/mozprofile/webapps.py b/testing/mozbase/mozprofile/mozprofile/webapps.py
index 4daf9ef06a..a9837f79e1 100644
--- a/testing/mozbase/mozprofile/mozprofile/webapps.py
+++ b/testing/mozbase/mozprofile/mozprofile/webapps.py
@@ -63,7 +63,7 @@ class Webapp(dict):
                 raise WebappFormatException("Webapp object missing required key '%s'" % key)
 
 
-class WebappCollection(object):
+class WebappCollection:
     """A list-like object that collects webapps and updates the webapp manifests"""
 
     json_template = Template(""""$name": {
@@ -110,7 +110,7 @@ class WebappCollection(object):
         :param json_template: [optional] string template describing the webapp json format
         :param manifest_template: [optional] string template describing the webapp manifest format
         """
-        if not isinstance(profile, basestring):
+        if not isinstance(profile, str):
             raise TypeError("Must provide path to a profile, received '%s'" % type(profile))
         self.profile = profile
         self.webapps_dir = os.path.join(self.profile, 'webapps')
@@ -123,7 +123,7 @@ class WebappCollection(object):
                 apps = [apps]
 
             for app in apps:
-                if isinstance(app, basestring) and os.path.isfile(app):
+                if isinstance(app, str) and os.path.isfile(app):
                     self.extend(self.read_json(app))
                 else:
                     self.append(app)
@@ -259,13 +259,13 @@ class WebappCollection(object):
 
         Returns a list of Webapp objects
         """
-        f = open(path, 'r')
+        f = open(path)
         app_json = json.load(f)
         f.close()
 
         apps = []
         if isinstance(app_json, dict):
-            for k, v in app_json.iteritems():
+            for k, v in app_json.items():
                 v['name'] = k
                 apps.append(v)
         else:
diff --git a/testing/mozbase/mozprofile/tests/addon_stubs.py b/testing/mozbase/mozprofile/tests/addon_stubs.py
index f9602de462..9675e314d8 100644
--- a/testing/mozbase/mozprofile/tests/addon_stubs.py
+++ b/testing/mozbase/mozprofile/tests/addon_stubs.py
@@ -34,23 +34,23 @@ def generate_addon(addon_id, path=None, name=None, xpi=True):
     Returns the file-path of the addon's .xpi file
     """
 
-    if addon_id not in stubs.keys():
-        raise IOError('Requested addon stub "%s" does not exist' % addon_id)
+    if addon_id not in list(stubs.keys()):
+        raise OSError('Requested addon stub "%s" does not exist' % addon_id)
 
     # Generate directory structure for addon
     try:
         tmpdir = path or tempfile.mkdtemp()
         addon_dir = os.path.join(tmpdir, name or addon_id)
         os.mkdir(addon_dir)
-    except IOError:
-        raise IOError('Could not generate directory structure for addon stub.')
+    except OSError:
+        raise OSError('Could not generate directory structure for addon stub.')
 
     # Write install.rdf for addon
     if stubs[addon_id]:
         install_rdf = os.path.join(addon_dir, 'install.rdf')
         with open(install_rdf, 'w') as f:
             manifest = os.path.join(here, 'install_manifests', stubs[addon_id])
-            f.write(open(manifest, 'r').read())
+            f.write(open(manifest).read())
 
     if not xpi:
         return addon_dir
diff --git a/testing/mozbase/mozprofile/tests/server_locations.py b/testing/mozbase/mozprofile/tests/server_locations.py
index 5aa5c0f5eb..6ab58879d1 100644
--- a/testing/mozbase/mozprofile/tests/server_locations.py
+++ b/testing/mozbase/mozprofile/tests/server_locations.py
@@ -60,21 +60,21 @@ http://example.org:80           privileged
         # ensure that they're what we expect
         self.assertEqual(len(locations), 6)
         i = iter(locations)
-        self.compare_location(i.next(), 'http', 'mochi.test', '8888',
+        self.compare_location(next(i), 'http', 'mochi.test', '8888',
                               ['primary', 'privileged'])
-        self.compare_location(i.next(), 'http', '127.0.0.1', '80',
+        self.compare_location(next(i), 'http', '127.0.0.1', '80',
                               ['privileged'])
-        self.compare_location(i.next(), 'http', '127.0.0.1', '8888',
+        self.compare_location(next(i), 'http', '127.0.0.1', '8888',
                               ['privileged'])
-        self.compare_location(i.next(), 'https', 'test', '80', ['privileged'])
-        self.compare_location(i.next(), 'http', 'example.org', '80',
+        self.compare_location(next(i), 'https', 'test', '80', ['privileged'])
+        self.compare_location(next(i), 'http', 'example.org', '80',
                               ['privileged'])
-        self.compare_location(i.next(), 'http', 'test1.example.org', '8888',
+        self.compare_location(next(i), 'http', 'test1.example.org', '8888',
                               ['privileged'])
 
         locations.add_host('mozilla.org')
         self.assertEqual(len(locations), 7)
-        self.compare_location(i.next(), 'http', 'mozilla.org', '80',
+        self.compare_location(next(i), 'http', 'mozilla.org', '80',
                               ['privileged'])
 
         # test some errors
@@ -116,7 +116,7 @@ http://example.org:80           privileged
         self.assertEqual(exc.lineno, 4)
 
     def test_server_locations_callback(self):
-        class CallbackTest(object):
+        class CallbackTest:
             last_locations = None
 
             def callback(self, locations):
diff --git a/testing/mozbase/mozprofile/tests/test_addons.py b/testing/mozbase/mozprofile/tests/test_addons.py
index 93b930feac..171c6ce497 100644
--- a/testing/mozbase/mozprofile/tests/test_addons.py
+++ b/testing/mozbase/mozprofile/tests/test_addons.py
@@ -8,7 +8,7 @@ import os
 import shutil
 import tempfile
 import unittest
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 
 from manifestparser import ManifestParser
 import mozfile
@@ -17,6 +17,7 @@ import mozlog.unstructured as mozlog
 import mozprofile
 
 from addon_stubs import generate_addon, generate_manifest
+import six
 
 
 here = os.path.dirname(os.path.abspath(__file__))
@@ -99,7 +100,7 @@ class TestAddonsManager(unittest.TestCase):
 
         # Download from an invalid URL
         addon = server.get_url() + 'not_existent.xpi'
-        self.assertRaises(urllib2.HTTPError,
+        self.assertRaises(six.moves.urllib.error.HTTPError,
                           self.am.download, addon, self.tmpdir)
         self.assertEqual(os.listdir(self.tmpdir), [])
 
@@ -122,7 +123,7 @@ class TestAddonsManager(unittest.TestCase):
             self.am.install_from_path(temp_addon)
 
         # Generate a list of addons installed in the profile
-        addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+        addons_installed = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
                             self.profile.profile, 'extensions', 'staged'))]
         self.assertEqual(addons_to_install.sort(), addons_installed.sort())
 
@@ -287,7 +288,7 @@ class TestAddonsManager(unittest.TestCase):
 
         self.am.install_from_manifest(temp_manifest)
         # Generate a list of addons installed in the profile
-        addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+        addons_installed = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
                             self.profile.profile, 'extensions', 'staged'))]
         self.assertEqual(addons_installed.sort(), addons_to_install.sort())
 
@@ -327,7 +328,7 @@ class TestAddonsManager(unittest.TestCase):
         addon_two = generate_addon('test-addon-2@mozilla.org')
 
         self.am.install_addons(addon_one)
-        installed_addons = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+        installed_addons = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
                             self.profile.profile, 'extensions', 'staged'))]
 
         # Create a new profile based on an existing profile
@@ -337,7 +338,7 @@ class TestAddonsManager(unittest.TestCase):
                                                        addons=addon_two)
         duplicate_profile.addon_manager.clean()
 
-        addons_after_cleanup = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+        addons_after_cleanup = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
                                 duplicate_profile.profile, 'extensions', 'staged'))]
         # New addons installed should be removed by clean_addons()
         self.assertEqual(installed_addons, addons_after_cleanup)
diff --git a/testing/mozbase/mozprofile/tests/test_preferences.py b/testing/mozbase/mozprofile/tests/test_preferences.py
index 45d99c2e27..9ff9fc62dc 100755
--- a/testing/mozbase/mozprofile/tests/test_preferences.py
+++ b/testing/mozbase/mozprofile/tests/test_preferences.py
@@ -62,9 +62,9 @@ class PreferencesTest(unittest.TestCase):
 
         _prefs = {"browser.startup.homepage": "http://planet.mozilla.org/"}
         commandline = []
-        _prefs = _prefs.items()
+        _prefs = list(_prefs.items())
         for pref, value in _prefs:
-            commandline += ["--pref", "%s:%s" % (pref, value)]
+            commandline += ["--pref", "{}:{}".format(pref, value)]
         self.compare_generated(_prefs, commandline)
 
     def test_ordered_prefs(self):
@@ -75,7 +75,7 @@ class PreferencesTest(unittest.TestCase):
                   ("webgl.verbose", 'false')]
         commandline = []
         for pref, value in _prefs:
-            commandline += ["--pref", "%s:%s" % (pref, value)]
+            commandline += ["--pref", "{}:{}".format(pref, value)]
         _prefs = [(i, Preferences.cast(j)) for i, j in _prefs]
         self.compare_generated(_prefs, commandline)
 
@@ -138,14 +138,14 @@ general.warnOnAboutConfig = False
         # we shouldn't have any initial preferences
         initial_prefs = Preferences.read_prefs(prefs_file)
         self.assertFalse(initial_prefs)
-        initial_prefs = file(prefs_file).read().strip()
+        initial_prefs = open(prefs_file).read().strip()
         self.assertFalse(initial_prefs)
 
         # add some preferences
         prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
         profile.set_preferences(prefs1)
         self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
-        lines = file(prefs_file).read().strip().splitlines()
+        lines = open(prefs_file).read().strip().splitlines()
         self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
         self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))
 
@@ -162,14 +162,14 @@ general.warnOnAboutConfig = False
         # we shouldn't have any initial preferences
         initial_prefs = Preferences.read_prefs(prefs_file)
         self.assertFalse(initial_prefs)
-        initial_prefs = file(prefs_file).read().strip()
+        initial_prefs = open(prefs_file).read().strip()
         self.assertFalse(initial_prefs)
 
         # add some preferences
         prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
         profile.set_persistent_preferences(prefs1)
         self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
-        lines = file(prefs_file).read().strip().splitlines()
+        lines = open(prefs_file).read().strip().splitlines()
         self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
         self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))
 
@@ -187,7 +187,7 @@ general.warnOnAboutConfig = False
         # we shouldn't have any initial preferences
         initial_prefs = Preferences.read_prefs(prefs_file)
         self.assertFalse(initial_prefs)
-        initial_prefs = file(prefs_file).read().strip()
+        initial_prefs = open(prefs_file).read().strip()
         self.assertFalse(initial_prefs)
 
         # add some preferences
@@ -195,7 +195,7 @@ general.warnOnAboutConfig = False
                   ("zoom.minPercent", 30)]
         profile.set_preferences(prefs1)
         self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
-        lines = file(prefs_file).read().strip().splitlines()
+        lines = open(prefs_file).read().strip().splitlines()
         self.assertTrue(bool([line for line in lines
                               if line.startswith('#MozRunner Prefs Start')]))
         self.assertTrue(bool([line for line in lines
@@ -206,7 +206,7 @@ general.warnOnAboutConfig = False
                   ("webgl.verbose", 'false')]
         profile.set_preferences(prefs2)
         self.assertEqual(prefs1 + prefs2, Preferences.read_prefs(prefs_file))
-        lines = file(prefs_file).read().strip().splitlines()
+        lines = open(prefs_file).read().strip().splitlines()
         self.assertTrue(len([line for line in lines
                              if line.startswith('#MozRunner Prefs Start')]) == 2)
         self.assertTrue(len([line for line in lines
@@ -216,7 +216,7 @@ general.warnOnAboutConfig = False
         profile.clean_preferences()
         final_prefs = Preferences.read_prefs(prefs_file)
         self.assertFalse(final_prefs)
-        lines = file(prefs_file).read().strip().splitlines()
+        lines = open(prefs_file).read().strip().splitlines()
         self.assertTrue('#MozRunner Prefs Start' not in lines)
         self.assertTrue('#MozRunner Prefs End' not in lines)
 
@@ -233,7 +233,7 @@ user_pref("webgl.enabled_for_all_sites", true);
 user_pref("webgl.force-enabled", true);
 """
             user_js = os.path.join(tempdir, 'user.js')
-            f = file(user_js, 'w')
+            f = open(user_js, 'w')
             f.write(contents)
             f.close()
 
diff --git a/testing/mozbase/mozprofile/tests/test_profile_view.py b/testing/mozbase/mozprofile/tests/test_profile_view.py
index 2e10a913bd..f6a56e708d 100644
--- a/testing/mozbase/mozprofile/tests/test_profile_view.py
+++ b/testing/mozbase/mozprofile/tests/test_profile_view.py
@@ -20,9 +20,9 @@ class TestProfilePrint(unittest.TestCase):
         test the summary function
         """
 
-        keys = set(['Files', 'Path', 'user.js'])
+        keys = {'Files', 'Path', 'user.js'}
         ff_prefs = mozprofile.FirefoxProfile.preferences  # shorthand
-        pref_string = '\n'.join(['%s: %s' % (key, ff_prefs[key])
+        pref_string = '\n'.join(['{}: {}'.format(key, ff_prefs[key])
                                  for key in sorted(ff_prefs.keys())])
 
         tempdir = tempfile.mkdtemp()
@@ -57,17 +57,17 @@ class TestProfilePrint(unittest.TestCase):
 
         # diff two profiles
         diff = dict(mozprofile.diff(profile1, profile2))
-        self.assertEqual(diff.keys(), ['user.js'])
+        self.assertEqual(list(diff.keys()), ['user.js'])
         lines = [line.strip() for line in diff['user.js'].splitlines()]
         self.assertTrue('+foo: bar' in lines)
 
         # diff a blank vs FirefoxProfile
         ff_profile = mozprofile.FirefoxProfile()
         diff = dict(mozprofile.diff(profile2, ff_profile))
-        self.assertEqual(diff.keys(), ['user.js'])
+        self.assertEqual(list(diff.keys()), ['user.js'])
         lines = [line.strip() for line in diff['user.js'].splitlines()]
         self.assertTrue('-foo: bar' in lines)
-        ff_pref_lines = ['+%s: %s' % (key, value)
+        ff_pref_lines = ['+{}: {}'.format(key, value)
                          for key, value in mozprofile.FirefoxProfile.preferences.items()]
         self.assertTrue(set(ff_pref_lines).issubset(lines))
 
diff --git a/testing/mozbase/mozprofile/tests/test_webapps.py b/testing/mozbase/mozprofile/tests/test_webapps.py
index 4db992d696..e72bb5ae4e 100755
--- a/testing/mozbase/mozprofile/tests/test_webapps.py
+++ b/testing/mozbase/mozprofile/tests/test_webapps.py
@@ -94,7 +94,7 @@ class WebappTest(unittest.TestCase):
         self.assertEqual(len(webapps), 2)
         self.assertTrue(webapp_1 in webapps)
         self.assertTrue(webapp_2 in webapps)
-        self.assertNotEquals(webapps[0], webapps[1])
+        self.assertNotEqual(webapps[0], webapps[1])
 
         # Insert a webapp object
         webapps.insert(1, webapp_3)
diff --git a/testing/mozbase/mozrunner/mozrunner/__init__.py b/testing/mozbase/mozrunner/mozrunner/__init__.py
index 0fec5c2386..5753de41f8 100644
--- a/testing/mozbase/mozrunner/mozrunner/__init__.py
+++ b/testing/mozbase/mozrunner/mozrunner/__init__.py
@@ -6,6 +6,6 @@ from .cli import *
 from .errors import *
 from .runners import *
 
-import base
-import devices
-import utils
+from . import base
+from . import devices
+from . import utils
diff --git a/testing/mozbase/mozrunner/mozrunner/application.py b/testing/mozbase/mozrunner/mozrunner/application.py
index 6734487ae6..eb874cfa5a 100644
--- a/testing/mozbase/mozrunner/mozrunner/application.py
+++ b/testing/mozbase/mozrunner/mozrunner/application.py
@@ -15,6 +15,7 @@ from mozprofile import (
     MetroFirefoxProfile,
     ThunderbirdProfile
 )
+import six
 
 here = os.path.abspath(os.path.dirname(__file__))
 
@@ -31,12 +32,11 @@ def get_app_context(appname):
     return context_map[appname]
 
 
-class DefaultContext(object):
+class DefaultContext:
     profile_class = Profile
 
 
-class RemoteContext(object):
-    __metaclass__ = ABCMeta
+class RemoteContext(six.with_metaclass(ABCMeta)):
     _dm = None
     _remote_profile = None
     _adb = None
@@ -243,15 +243,15 @@ class B2GContext(RemoteContext):
             self.dm.shellCheckOutput(['touch', self.remote_settings_db])
 
 
-class FirefoxContext(object):
+class FirefoxContext:
     profile_class = FirefoxProfile
 
 
-class ThunderbirdContext(object):
+class ThunderbirdContext:
     profile_class = ThunderbirdProfile
 
 
-class MetroContext(object):
+class MetroContext:
     profile_class = MetroFirefoxProfile
 
     def __init__(self, binary=None):
diff --git a/testing/mozbase/mozrunner/mozrunner/base/browser.py b/testing/mozbase/mozrunner/mozrunner/base/browser.py
index 6fc7348d58..9b53d09d34 100644
--- a/testing/mozbase/mozrunner/mozrunner/base/browser.py
+++ b/testing/mozbase/mozrunner/mozrunner/base/browser.py
@@ -35,7 +35,7 @@ class GeckoRuntimeRunner(BaseRunner):
         if sys.platform == 'linux2' and self.binary.endswith('-bin'):
             dirname = os.path.dirname(self.binary)
             if os.environ.get('LD_LIBRARY_PATH', None):
-                self.env['LD_LIBRARY_PATH'] = '%s:%s' % (os.environ['LD_LIBRARY_PATH'], dirname)
+                self.env['LD_LIBRARY_PATH'] = '{}:{}'.format(os.environ['LD_LIBRARY_PATH'], dirname)
             else:
                 self.env['LD_LIBRARY_PATH'] = dirname
 
diff --git a/testing/mozbase/mozrunner/mozrunner/base/device.py b/testing/mozbase/mozrunner/mozrunner/base/device.py
index 6eeef042f4..14b2ba59b9 100644
--- a/testing/mozbase/mozrunner/mozrunner/base/device.py
+++ b/testing/mozbase/mozrunner/mozrunner/base/device.py
@@ -2,8 +2,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from __future__ import print_function
 
+from __future__ import print_function
 import datetime
 import re
 import signal
@@ -59,8 +59,8 @@ class DeviceRunner(BaseRunner):
         if self.app_ctx.dm._deviceSerial:
             cmd.extend(['-s', self.app_ctx.dm._deviceSerial])
         cmd.append('shell')
-        for k, v in self._device_env.iteritems():
-            cmd.append('%s=%s' % (k, v))
+        for k, v in self._device_env.items():
+            cmd.append('{}={}'.format(k, v))
         cmd.append(self.app_ctx.remote_binary)
         return cmd
 
@@ -87,7 +87,7 @@ class DeviceRunner(BaseRunner):
                 break
             time.sleep(1)
         else:
-            print("timed out waiting for '%s' process to start" % self.app_ctx.remote_process)
+            print(("timed out waiting for '%s' process to start" % self.app_ctx.remote_process))
 
         if not self.device.wait_for_net():
             raise Exception("Failed to get a network connection")
@@ -108,17 +108,17 @@ class DeviceRunner(BaseRunner):
             self.app_ctx.dm.killProcess(
                 self.app_ctx.remote_process, sig=sig)
             if not _wait_for_shutdown(remote_pid) and sig is not None:
-                print("timed out waiting for '%s' process to exit, trying "
+                print(("timed out waiting for '%s' process to exit, trying "
                       "without signal {}".format(
-                          self.app_ctx.remote_process, sig))
+                          self.app_ctx.remote_process, sig)))
 
             # need to call adb stop otherwise the system will attempt to
             # restart the process
             remote_pid = self.is_running() or remote_pid
             self.app_ctx.stop_application()
             if not _wait_for_shutdown(remote_pid):
-                print("timed out waiting for '%s' process to exit".format(
-                    self.app_ctx.remote_process))
+                print(("timed out waiting for '%s' process to exit".format(
+                    self.app_ctx.remote_process)))
 
     def is_running(self):
         return self.app_ctx.dm.processExist(self.app_ctx.remote_process)
@@ -137,7 +137,7 @@ class DeviceRunner(BaseRunner):
             timeout = self.output_timeout
             msg = "%s with no output" % msg
 
-        print(msg % (self.last_test, timeout))
+        print((msg % (self.last_test, timeout)))
         self.check_for_crashes()
 
     def on_finish(self):
@@ -163,7 +163,7 @@ class DeviceRunner(BaseRunner):
 class FennecRunner(DeviceRunner):
 
     def __init__(self, cmdargs=None, **kwargs):
-        super(FennecRunner, self).__init__(**kwargs)
+        super().__init__(**kwargs)
         self.cmdargs = cmdargs or []
 
     @property
@@ -178,7 +178,7 @@ class FennecRunner(DeviceRunner):
         app_params.extend(self.cmdargs)
         am_subcommand.extend(["--es", "args", "'%s'" % " ".join(app_params)])
         # Append env variables in the form |--es env0 MOZ_CRASHREPORTER=1|
-        for (count, (k, v)) in enumerate(self._device_env.iteritems()):
-            am_subcommand.extend(["--es", "env%d" % count, "%s=%s" % (k, v)])
+        for (count, (k, v)) in enumerate(self._device_env.items()):
+            am_subcommand.extend(["--es", "env%d" % count, "{}={}".format(k, v)])
         cmd.append("%s" % " ".join(am_subcommand))
         return cmd
diff --git a/testing/mozbase/mozrunner/mozrunner/base/runner.py b/testing/mozbase/mozrunner/mozrunner/base/runner.py
index 98628f6f33..f187bcf680 100644
--- a/testing/mozbase/mozrunner/mozrunner/base/runner.py
+++ b/testing/mozbase/mozrunner/mozrunner/base/runner.py
@@ -10,6 +10,7 @@ import traceback
 
 from mozlog import get_default_logger
 from mozprocess import ProcessHandler
+import six
 try:
     import mozcrash
 except ImportError:
@@ -19,11 +20,10 @@ from ..application import DefaultContext
 from ..errors import RunnerNotStartedError
 
 
-class BaseRunner(object):
+class BaseRunner(six.with_metaclass(ABCMeta)):
     """
     The base runner class for all mozrunner objects, both local and remote.
     """
-    __metaclass__ = ABCMeta
     last_test = 'mozrunner-startup'
     process_handler = None
     timeout = None
@@ -34,7 +34,7 @@ class BaseRunner(object):
                  dump_save_path=None, addons=None):
         self.app_ctx = app_ctx or DefaultContext()
 
-        if isinstance(profile, basestring):
+        if isinstance(profile, str):
             self.profile = self.app_ctx.profile_class(profile=profile,
                                                       addons=addons)
         else:
diff --git a/testing/mozbase/mozrunner/mozrunner/cli.py b/testing/mozbase/mozrunner/mozrunner/cli.py
index 9b340edb66..657f088f74 100644
--- a/testing/mozbase/mozrunner/mozrunner/cli.py
+++ b/testing/mozbase/mozrunner/mozrunner/cli.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import sys
 
@@ -63,7 +64,7 @@ class CLI(MozProfileCLI):
             self.profile_class = get_app_context(app).profile_class
         except KeyError:
             self.parser.error('Application "%s" unknown (should be one of "%s")' %
-                              (app, ', '.join(runners.keys())))
+                              (app, ', '.join(list(runners.keys()))))
 
     def add_options(self, parser):
         """add options to the parser"""
@@ -95,7 +96,7 @@ class CLI(MozProfileCLI):
 
     def command_args(self):
         """additional arguments for the mozilla application"""
-        return map(os.path.expanduser, self.options.appArgs)
+        return list(map(os.path.expanduser, self.options.appArgs))
 
     def runner_args(self):
         """arguments to instantiate the runner class"""
@@ -137,7 +138,7 @@ class CLI(MozProfileCLI):
         # attach a debugger if specified
         debug_args, interactive = self.debugger_arguments()
         runner.start(debug_args=debug_args, interactive=interactive)
-        print 'Starting: ' + ' '.join(runner.command)
+        print(('Starting: ' + ' '.join(runner.command)))
         try:
             runner.wait()
         except KeyboardInterrupt:
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/__init__.py b/testing/mozbase/mozrunner/mozrunner/devices/__init__.py
index bdb7586c90..26f816ab17 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/__init__.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/__init__.py
@@ -2,12 +2,12 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from emulator import BaseEmulator, Emulator, EmulatorAVD
-from base import Device
+from .emulator import BaseEmulator, Emulator, EmulatorAVD
+from .base import Device
 
-import emulator_battery
-import emulator_geo
-import emulator_screen
+from . import emulator_battery
+from . import emulator_geo
+from . import emulator_screen
 
 __all__ = ['BaseEmulator', 'Emulator', 'EmulatorAVD', 'Device',
            'emulator_battery', 'emulator_geo', 'emulator_screen']
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
index 0052f473c9..6670c66774 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import fileinput
 import glob
 import os
@@ -12,8 +13,8 @@ import signal
 import sys
 import telnetlib
 import time
-import urlparse
-import urllib2
+import six.moves.urllib.parse
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 from distutils.spawn import find_executable
 
 from mozdevice import DeviceManagerADB, DMError
@@ -96,7 +97,7 @@ def verify_android_device(build_obj, install=False, xre=False, debugger=False, v
     if (len(devices) > 0) and ('device' in [d[1] for d in devices]):
         device_verified = True
     elif emulator.is_available():
-        response = raw_input(
+        response = input(
             "No Android devices connected. Start an emulator? (Y/n) ").strip()
         if response.lower().startswith('y') or response == '':
             if not emulator.check_avd():
@@ -124,7 +125,7 @@ def verify_android_device(build_obj, install=False, xre=False, debugger=False, v
         installed = emulator.dm.shellCheckOutput(['pm', 'list',
                                                   'packages', 'org.mozilla.'])
         if 'fennec' not in installed and 'firefox' not in installed:
-            response = raw_input(
+            response = input(
                 "It looks like Firefox is not installed on this device.\n"
                 "Install Firefox? (Y/n) ").strip()
             if response.lower().startswith('y') or response == '':
@@ -153,7 +154,7 @@ def verify_android_device(build_obj, install=False, xre=False, debugger=False, v
                     break
         if err:
             _log_info("Host utilities not found: %s" % err)
-            response = raw_input(
+            response = input(
                 "Download and setup your host utilities? (Y/n) ").strip()
             if response.lower().startswith('y') or response == '':
                 _log_info("Installing host utilities. This may take a while...")
@@ -188,7 +189,7 @@ def verify_android_device(build_obj, install=False, xre=False, debugger=False, v
             err = '%s not found' % gdb_path
         if err:
             _log_info("JimDB (%s) not found: %s" % (build_platform, err))
-            response = raw_input(
+            response = input(
                 "Download and setup JimDB (%s)? (Y/n) " % build_platform).strip()
             if response.lower().startswith('y') or response == '':
                 host_platform = _get_host_platform()
@@ -252,7 +253,7 @@ def run_firefox_for_android(build_obj, params):
         cmd = ['am', 'start', '-a', 'android.activity.MAIN', '-n', app]
         if params:
             for p in params:
-                if urlparse.urlparse(p).scheme != "":
+                if six.moves.urllib.parse.urlparse(p).scheme != "":
                     cmd.extend(['-d', p])
                     params.remove(p)
                     break
@@ -570,7 +571,7 @@ class AndroidEmulator(object):
         return telnet_ok
 
     def _get_avd_type(self, requested):
-        if requested in AVD_DICT.keys():
+        if requested in list(AVD_DICT.keys()):
             return requested
         if self.substs:
             if not self.substs['TARGET_CPU'].startswith('arm'):
@@ -646,23 +647,23 @@ def _find_sdk_exe(substs, exe, tools):
 
 def _log_debug(text):
     if verbose_logging:
-        print "DEBUG: %s" % text
+        print(("DEBUG: %s" % text))
 
 
 def _log_warning(text):
-    print "WARNING: %s" % text
+    print(("WARNING: %s" % text))
 
 
 def _log_info(text):
-    print "%s" % text
+    print(("%s" % text))
 
 
 def _download_file(url, filename, path):
-    f = urllib2.urlopen(url)
+    f = six.moves.urllib.request.urlopen(url)
     if not os.path.isdir(path):
         try:
             os.makedirs(path)
-        except Exception, e:
+        except Exception as e:
             _log_warning(str(e))
             return False
     local_file = open(os.path.join(path, filename), 'wb')
@@ -676,7 +677,7 @@ def _get_tooltool_manifest(substs, src_path, dst_path, filename):
     if not os.path.isdir(dst_path):
         try:
             os.makedirs(dst_path)
-        except Exception, e:
+        except Exception as e:
             _log_warning(str(e))
     copied = False
     if substs and 'top_srcdir' in substs:
@@ -750,13 +751,13 @@ def _update_gdbinit(substs, path):
         # update existing objdir/srcroot in place
         for line in fileinput.input(path, inplace=True):
             if "feninit.default.objdir" in line and substs and 'MOZ_BUILD_ROOT' in substs:
-                print("python feninit.default.objdir = '%s'" % substs['MOZ_BUILD_ROOT'])
+                print(("python feninit.default.objdir = '%s'" % substs['MOZ_BUILD_ROOT']))
                 obj_replaced = True
             elif "feninit.default.srcroot" in line and substs and 'top_srcdir' in substs:
-                print("python feninit.default.srcroot = '%s'" % substs['top_srcdir'])
+                print(("python feninit.default.srcroot = '%s'" % substs['top_srcdir']))
                 src_replaced = True
             else:
-                print(line.strip())
+                print((line.strip()))
         # append objdir/srcroot if not updated
         if (not obj_replaced) and substs and 'MOZ_BUILD_ROOT' in substs:
             with open(path, "a") as f:
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/autophone.py b/testing/mozbase/mozrunner/mozrunner/devices/autophone.py
index 3b4913028e..b648a13f71 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/autophone.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/autophone.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import glob
 import json
 import logging
@@ -13,15 +14,15 @@ import sys
 import threading
 import time
 import which
-import BaseHTTPServer
-import SimpleHTTPServer
+import six.moves.BaseHTTPServer
+import six.moves.SimpleHTTPServer
 
 from mozbuild.virtualenv import VirtualenvManager
 from mozdevice import DeviceManagerADB
 from mozprocess import ProcessHandler
 
 
-class AutophoneRunner(object):
+class AutophoneRunner:
     """
        Supporting the mach 'autophone' command: configure, run autophone.
     """
@@ -47,7 +48,7 @@ class AutophoneRunner(object):
             self.build_obj.log(logging.WARN, "autophone", {},
                                "*** This will delete %s and reset your "
                                "'mach autophone' configuration! ***" % dir)
-            response = raw_input(
+            response = input(
                 "Proceed with deletion? (y/N) ").strip()
             if response.lower().startswith('y'):
                 os.remove(self.CONFIG_FILE)
@@ -64,7 +65,7 @@ class AutophoneRunner(object):
             with open(self.CONFIG_FILE, 'w') as f:
                 json.dump(self.config, f)
             if self.verbose:
-                print("saved configuration: %s" % self.config)
+                print(("saved configuration: %s" % self.config))
         except:
             self.build_obj.log(logging.ERROR, "autophone", {},
                                "unable to save 'mach autophone' "
@@ -79,10 +80,10 @@ class AutophoneRunner(object):
         """
         if os.path.exists(self.CONFIG_FILE):
             try:
-                with open(self.CONFIG_FILE, 'r') as f:
+                with open(self.CONFIG_FILE) as f:
                     self.config = json.load(f)
                 if self.verbose:
-                    print("loaded configuration: %s" % self.config)
+                    print(("loaded configuration: %s" % self.config))
             except:
                 self.build_obj.log(logging.ERROR, "autophone", {},
                                    "unable to load 'mach autophone' "
@@ -100,7 +101,7 @@ class AutophoneRunner(object):
         if not dir:
             dir = os.path.join(os.path.expanduser('~'), 'mach-autophone')
         if os.path.exists(os.path.join(dir, '.git')):
-            response = raw_input(
+            response = input(
                 "Run autophone from existing directory, %s (Y/n) " % dir).strip()
             if 'n' not in response.lower():
                 self.build_obj.log(logging.INFO, "autophone", {},
@@ -109,7 +110,7 @@ class AutophoneRunner(object):
         self.build_obj.log(logging.INFO, "autophone", {},
                            "Unable to find an existing autophone directory. "
                            "Let's setup a new one...")
-        response = raw_input(
+        response = input(
             "Enter location of new autophone directory: [%s] " % dir).strip()
         if response != '':
             dir = response
@@ -160,7 +161,7 @@ class AutophoneRunner(object):
         keep_going = True
         device_ini = os.path.join(self.config['base-dir'], 'devices.ini')
         if os.path.exists(device_ini):
-            response = raw_input(
+            response = input(
                 "Use existing device configuration at %s? (Y/n) " % device_ini).strip()
             if 'n' not in response.lower():
                 self.build_obj.log(logging.INFO, "autophone", {},
@@ -170,10 +171,10 @@ class AutophoneRunner(object):
         self.build_obj.log(logging.INFO, "autophone", {},
                            "You must configure at least one Android device "
                            "before running autophone.")
-        response = raw_input(
+        response = input(
             "Configure devices now? (Y/n) ").strip()
         if response.lower().startswith('y') or response == '':
-            response = raw_input(
+            response = input(
                 "Connect your rooted Android test device(s) with usb and press Enter ")
             adb_path = 'adb'
             try:
@@ -187,10 +188,10 @@ class AutophoneRunner(object):
                 try:
                     adb_path = which.which('adb')
                 except which.WhichError:
-                    adb_path = raw_input(
+                    adb_path = input(
                         "adb not found. Enter path to adb: ").strip()
             if self.verbose:
-                print("Using adb at %s" % adb_path)
+                print(("Using adb at %s" % adb_path))
             dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
             device_index = 1
             try:
@@ -232,7 +233,7 @@ class AutophoneRunner(object):
                            "describing the type(s) of test(s) to run.")
         test_options = []
         for ini in glob.glob(os.path.join(dir, 'tests', '*.ini')):
-            with open(ini, 'r') as f:
+            with open(ini) as f:
                 content = f.readlines()
                 for line in content:
                     if line.startswith('# @mach@ '):
@@ -248,14 +249,14 @@ class AutophoneRunner(object):
                                "These test manifests are available:")
             index = 1
             for option in test_options:
-                print("%d. %s" % (index, option[0]))
+                print(("%d. %s" % (index, option[0])))
                 index += 1
             highest = index - 1
             path = None
             while not path:
                 path = None
                 self.webserver_required = False
-                response = raw_input(
+                response = input(
                     "Select test manifest (1-%d, or path to test manifest) " % highest).strip()
                 if os.path.isfile(response):
                     path = response
@@ -284,7 +285,7 @@ class AutophoneRunner(object):
             response = ""
             default = self.config['test-manifest'] or ""
             while not os.path.isfile(response):
-                response = raw_input(
+                response = input(
                     "Enter path to a test manifest: [%s] " % default).strip()
                 if response == "":
                     response = default
@@ -305,13 +306,13 @@ class AutophoneRunner(object):
                 f.write("""\
 # Created by 'mach autophone'
 [runtests]
-xre_path = %s
-utility_path = %s
+xre_path = {}
+utility_path = {}
 console_level = DEBUG
 log_level = DEBUG
-time_out = 300""" % (xre_path, xre_path))
+time_out = 300""".format(xre_path, xre_path))
             if self.verbose:
-                print("Created %s with host utilities path %s" % (defaults_path, xre_path))
+                print(("Created {} with host utilities path {}".format(defaults_path, xre_path)))
         except:
             self.build_obj.log(logging.ERROR, "autophone", {},
                                "Unable to create %s" % defaults_path)
@@ -325,7 +326,7 @@ time_out = 300""" % (xre_path, xre_path))
         """
         defaults_path = os.path.join(self.config['base-dir'], 'configs', 'unittest-defaults.ini')
         if os.path.isfile(defaults_path):
-            response = raw_input(
+            response = input(
                 "Use existing unit test configuration at %s? (Y/n) " % defaults_path).strip()
             if 'n' in response.lower():
                 os.remove(defaults_path)
@@ -343,7 +344,7 @@ time_out = 300""" % (xre_path, xre_path))
                 self.build_obj.log(logging.INFO, "autophone", {},
                                    "Some tests require access to 'host utilities' "
                                    "such as xpcshell.")
-                xre_path = raw_input(
+                xre_path = input(
                     "Enter path to host utilities directory: ").strip()
                 if not xre_path or not os.path.isdir(xre_path) or \
                    not os.path.isfile(os.path.join(xre_path, 'xpcshell')):
@@ -366,7 +367,7 @@ time_out = 300""" % (xre_path, xre_path))
         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
         s.connect(('8.8.8.8', 0))
         ip = s.getsockname()[0]
-        response = raw_input(
+        response = input(
             "IP address of interface to use for phone callbacks [%s] " % ip).strip()
         if response == "":
             response = ip
@@ -381,10 +382,10 @@ time_out = 300""" % (xre_path, xre_path))
         if self.webserver_required:
             self.build_obj.log(logging.INFO, "autophone", {},
                                "Some of your selected tests require a webserver.")
-            response = raw_input("Start a webserver now? [Y/n] ").strip()
+            response = input("Start a webserver now? [Y/n] ").strip()
             parts = []
             while len(parts) != 2:
-                response2 = raw_input(
+                response2 = input(
                     "Webserver address? [%s:8100] " % self.ipaddr).strip()
                 if response2 == "":
                     parts = [self.ipaddr, "8100"]
@@ -496,7 +497,7 @@ time_out = 300""" % (xre_path, xre_path))
                 "Type 'trigger', 'help', 'quit', or an autophone command.")
         quitting = False
         while self.thread.isAlive() and not quitting:
-            response = raw_input(
+            response = input(
                 "autophone command? ").strip().lower()
             if response == "help":
                 self.run_process(['./ap.sh', 'autophone-help'], cwd=dir, dump=True)
@@ -545,7 +546,7 @@ quit
         highest = 4
         choice = 0
         while (choice < 1 or choice > highest):
-            response = raw_input(
+            response = input(
                 "Build selection type? (1-%d) " % highest).strip()
             try:
                 choice = int(response)
@@ -556,18 +557,18 @@ quit
         if choice == 1:
             options = ["latest"]
         elif choice == 2:
-            url = raw_input(
+            url = input(
                 "Enter url of build to test; may be an http or file schema ").strip()
             options = ["--build-url=%s" % url]
         elif choice == 3:
-            response = raw_input(
+            response = input(
                 "Enter Build ID, eg 20120403063158 ").strip()
             options = [response]
         elif choice == 4:
-            start = raw_input(
+            start = input(
                 "Enter start build date or date-time, "
                 "e.g. 2012-04-03 or 2012-04-03T06:31:58 ").strip()
-            end = raw_input(
+            end = input(
                 "Enter end build date or date-time, "
                 "e.g. 2012-04-03 or 2012-04-03T06:31:58 ").strip()
             options = [start, end]
@@ -577,7 +578,7 @@ quit
         self.build_obj.log(
             logging.INFO, "autophone", {},
             "If not specified, 'mozilla-central' is assumed.")
-        repo = raw_input(
+        repo = input(
             "Enter repository name: ").strip()
         if len(repo) > 0:
             options.extend(["--repo=%s" % repo])
@@ -585,7 +586,7 @@ quit
             self.build_obj.log(
                 logging.INFO, "autophone", {},
                 "You may optionally specify the build location, like 'nightly' or 'tinderbox'.")
-            location = raw_input(
+            location = input(
                 "Enter build location: ").strip()
             if len(location) > 0:
                 options.extend(["--build-location=%s" % location])
@@ -612,7 +613,7 @@ quit
         self.threadweb.start()
 
     def run_webserver(self):
-        class AutoHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+        class AutoHTTPRequestHandler(six.moves.SimpleHTTPServer.SimpleHTTPRequestHandler):
             # A simple request handler with logging suppressed.
 
             def log_message(self, format, *args):
@@ -620,7 +621,7 @@ quit
 
         os.chdir(self.config['base-dir'])
         address = (self.webserver_addr, self.webserver_port)
-        self.httpd = BaseHTTPServer.HTTPServer(address, AutoHTTPRequestHandler)
+        self.httpd = six.moves.BaseHTTPServer.HTTPServer(address, AutoHTTPRequestHandler)
         try:
             self.httpd.serve_forever()
         except KeyboardInterrupt:
@@ -633,7 +634,7 @@ quit
 
         if self.verbose:
             self.build_obj.log(logging.INFO, "autophone", {},
-                               "Running '%s' in '%s'" % (cmd, cwd))
+                               "Running '{}' in '{}'".format(cmd, cwd))
         proc = ProcessHandler(cmd, cwd=cwd, processOutputLine=_processOutput,
                               processStderrLine=_processOutput)
         proc.run()
@@ -647,5 +648,5 @@ quit
                 proc.kill(signal.SIGTERM)
         if not proc_complete:
             if not self.verbose:
-                print(proc.output)
+                print((proc.output))
         return proc_complete
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/base.py b/testing/mozbase/mozrunner/mozrunner/devices/base.py
index b5cf2b58fb..a0d9004d38 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/base.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/base.py
@@ -1,4 +1,5 @@
-from ConfigParser import (
+from __future__ import print_function
+from configparser import (
     ConfigParser,
     RawConfigParser
 )
@@ -89,7 +90,7 @@ class Device(object):
                 break
             time.sleep(1)
         else:
-            print "timed out waiting for profiles.ini"
+            print("timed out waiting for profiles.ini")
 
         local_profiles_ini = tempfile.NamedTemporaryFile()
         self.dm.getFile(self.app_ctx.remote_profiles_ini, local_profiles_ini.name)
@@ -175,7 +176,7 @@ class Device(object):
         :param busybox: Path to busybox binary to install.
         """
         self.dm.remount()
-        print 'pushing %s' % self.app_ctx.remote_busybox
+        print(('pushing %s' % self.app_ctx.remote_busybox))
         self.dm.pushFile(busybox, self.app_ctx.remote_busybox, retryLimit=10)
         # TODO for some reason using dm.shellCheckOutput doesn't work,
         #      while calling adb shell directly does.
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/emulator.py b/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
index adeae27ed7..5a14aaa7ba 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
@@ -19,7 +19,7 @@ from .emulator_screen import EmulatorScreen
 from ..errors import TimeoutException
 
 
-class ArchContext(object):
+class ArchContext:
 
     def __init__(self, arch, context, binary=None, avd=None, extra_args=None):
         homedir = getattr(context, 'homedir', '')
@@ -49,7 +49,7 @@ class ArchContext(object):
             self.extra_args.extend(extra_args)
 
 
-class SDCard(object):
+class SDCard:
 
     def __init__(self, emulator, size):
         self.emulator = emulator
@@ -82,7 +82,7 @@ class BaseEmulator(Device):
         self.arch = ArchContext(kwargs.pop('arch', 'arm'), app_ctx,
                                 binary=kwargs.pop('binary', None),
                                 avd=kwargs.pop('avd', None))
-        super(BaseEmulator, self).__init__(app_ctx, **kwargs)
+        super().__init__(app_ctx, **kwargs)
         self.tmpdir = tempfile.mkdtemp()
         # These rely on telnet
         self.battery = EmulatorBattery(self)
@@ -125,7 +125,7 @@ class BaseEmulator(Device):
 
         devices = set(self._get_online_devices())
         now = datetime.datetime.now()
-        while (devices - original_devices) == set([]):
+        while (devices - original_devices) == set():
             time.sleep(1)
             # Sometimes it takes more than 60s to launch emulator, so we
             # increase timeout value to 180s. Please see bug 1143380.
@@ -150,7 +150,7 @@ class BaseEmulator(Device):
         if self.connected:
             return
 
-        super(BaseEmulator, self).connect()
+        super().connect()
         serial = self.serial or self.dm._deviceSerial
         self.port = int(serial[serial.rindex('-') + 1:])
 
@@ -158,7 +158,7 @@ class BaseEmulator(Device):
         """
         Cleans up and kills the emulator, if it was started by mozrunner.
         """
-        super(BaseEmulator, self).cleanup()
+        super().cleanup()
         if self.proc:
             self.proc.kill()
             self.proc = None
@@ -196,7 +196,7 @@ class Emulator(BaseEmulator):
 
     def __init__(self, app_ctx, arch, resolution=None, sdcard=None, userdata=None,
                  no_window=None, binary=None, **kwargs):
-        super(Emulator, self).__init__(app_ctx, arch=arch, binary=binary, **kwargs)
+        super().__init__(app_ctx, arch=arch, binary=binary, **kwargs)
 
         # emulator args
         self.resolution = resolution or '320x480'
@@ -218,7 +218,7 @@ class Emulator(BaseEmulator):
         """
         Arguments to pass into the emulator binary.
         """
-        qemu_args = super(Emulator, self).args
+        qemu_args = super().args
         qemu_args.extend([
             '-kernel', self.arch.kernel,
             '-sysdir', self.arch.sysdir,
@@ -245,7 +245,7 @@ class Emulator(BaseEmulator):
         if self.connected:
             return
 
-        super(Emulator, self).connect()
+        super().connect()
         self.geo.set_default_location()
         self.screen.initialize()
 
@@ -256,7 +256,7 @@ class Emulator(BaseEmulator):
         """
         Cleans up and kills the emulator, if it was started by mozrunner.
         """
-        super(Emulator, self).cleanup()
+        super().cleanup()
         # Remove temporary files
         self.userdata.close()
 
@@ -264,7 +264,7 @@ class Emulator(BaseEmulator):
 class EmulatorAVD(BaseEmulator):
 
     def __init__(self, app_ctx, binary, avd, port=5554, **kwargs):
-        super(EmulatorAVD, self).__init__(app_ctx, binary=binary, avd=avd, **kwargs)
+        super().__init__(app_ctx, binary=binary, avd=avd, **kwargs)
         self.port = port
 
     @property
@@ -272,7 +272,7 @@ class EmulatorAVD(BaseEmulator):
         """
         Arguments to pass into the emulator binary.
         """
-        qemu_args = super(EmulatorAVD, self).args
+        qemu_args = super().args
         qemu_args.extend(['-avd', self.arch.avd,
                           '-port', str(self.port)])
         qemu_args.extend(self.arch.extra_args)
@@ -285,4 +285,4 @@ class EmulatorAVD(BaseEmulator):
         env = os.environ
         env['ANDROID_AVD_HOME'] = self.app_ctx.avd_home
 
-        super(EmulatorAVD, self).start()
+        super().start()
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/emulator_battery.py b/testing/mozbase/mozrunner/mozrunner/devices/emulator_battery.py
index 6f389152b2..9d7aab5baa 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator_battery.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator_battery.py
@@ -3,7 +3,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-class EmulatorBattery(object):
+class EmulatorBattery:
 
     def __init__(self, emulator):
         self.emulator = emulator
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/emulator_geo.py b/testing/mozbase/mozrunner/mozrunner/devices/emulator_geo.py
index a8ec0e0899..65bd56f3c8 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator_geo.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator_geo.py
@@ -3,7 +3,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-class EmulatorGeo(object):
+class EmulatorGeo:
 
     def __init__(self, emulator):
         self.emulator = emulator
@@ -14,4 +14,4 @@ class EmulatorGeo(object):
         self.set_location(self.lon, self.lat)
 
     def set_location(self, lon, lat):
-        self.emulator._run_telnet('geo fix %0.5f %0.5f' % (self.lon, self.lat))
+        self.emulator._run_telnet('geo fix {:0.5f} {:0.5f}'.format(self.lon, self.lat))
diff --git a/testing/mozbase/mozrunner/mozrunner/devices/emulator_screen.py b/testing/mozbase/mozrunner/mozrunner/devices/emulator_screen.py
index 58bdda8124..fa18567b5a 100644
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator_screen.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator_screen.py
@@ -3,7 +3,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-class EmulatorScreen(object):
+class EmulatorScreen:
     """Class for screen related emulator commands."""
 
     SO_PORTRAIT_PRIMARY = 'portrait-primary'
diff --git a/testing/mozbase/mozrunner/mozrunner/utils.py b/testing/mozbase/mozrunner/mozrunner/utils.py
index c26055f300..7c62df732c 100755
--- a/testing/mozbase/mozrunner/mozrunner/utils.py
+++ b/testing/mozbase/mozrunner/mozrunner/utils.py
@@ -6,6 +6,7 @@
 
 """Utility functions for mozrunner"""
 
+from __future__ import print_function
 import mozinfo
 import os
 import sys
@@ -63,7 +64,7 @@ def findInPath(fileName, path=os.environ['PATH']):
 
 if __name__ == '__main__':
     for i in sys.argv[1:]:
-        print findInPath(i)
+        print((findInPath(i)))
 
 
 def _find_marionette_in_args(*args, **kwargs):
diff --git a/testing/mozbase/mozrunner/tests/test_crash.py b/testing/mozbase/mozrunner/tests/test_crash.py
index 455fc5f72d..3048ed9f77 100644
--- a/testing/mozbase/mozrunner/tests/test_crash.py
+++ b/testing/mozbase/mozrunner/tests/test_crash.py
@@ -3,7 +3,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import mock
+from unittest import mock
 
 import mozrunnertest
 
diff --git a/testing/mozbase/mozscreenshot/mozscreenshot/__init__.py b/testing/mozbase/mozscreenshot/mozscreenshot/__init__.py
index 56c62cb23c..8f42d31c2f 100644
--- a/testing/mozbase/mozscreenshot/mozscreenshot/__init__.py
+++ b/testing/mozbase/mozscreenshot/mozscreenshot/__init__.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import mozinfo
 import tempfile
@@ -11,12 +12,12 @@ from mozlog.formatters.process import strstatus
 
 def printstatus(name, returncode):
     """
-    print the status of a command exit code, formatted for tbpl.
+    print(the status of a command exit code, formatted for tbpl.)
 
     Note that mozlog structured action "process_exit" should be used
     instead of that in new code.
     """
-    print "TEST-INFO | %s: %s" % (name, strstatus(returncode))
+    print(("TEST-INFO | %s: %s" % (name, strstatus(returncode))))
 
 
 def dump_screen(utilityPath, log):
@@ -56,6 +57,6 @@ def dump_screen(utilityPath, log):
             log.process_exit(utilityname, returncode)
         else:
             printstatus(utilityname, returncode)
-    except OSError, err:
+    except OSError as err:
         log.info("Failed to start %s for screenshot: %s"
                  % (utility[0], err.strerror))
diff --git a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
index 56a1f0ef70..a197e0185d 100644
--- a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
+++ b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
@@ -14,7 +14,7 @@ from collections import (
 )
 
 
-class PsutilStub(object):
+class PsutilStub:
 
     def __init__(self):
         self.sswap = namedtuple('sswap', ['total', 'used', 'free', 'percent', 'sin',
@@ -138,7 +138,7 @@ SystemResourceUsage = namedtuple('SystemResourceUsage',
                                   'cpu_times', 'cpu_percent', 'io', 'virt', 'swap'])
 
 
-class SystemResourceMonitor(object):
+class SystemResourceMonitor:
     """Measures system resources.
 
     Each instance measures system resources from the time it is started
diff --git a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py
index b6763e20e9..657a58770b 100644
--- a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py
+++ b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py
@@ -56,7 +56,7 @@ class TestResourceMonitor(unittest.TestCase):
         monitor.stop()
 
         self.assertEqual(len(monitor.phases), 2)
-        self.assertEqual(['phase2', 'phase1'], monitor.phases.keys())
+        self.assertEqual(['phase2', 'phase1'], list(monitor.phases.keys()))
 
         all = list(monitor.range_usage())
         data1 = list(monitor.phase_usage('phase1'))
@@ -146,7 +146,7 @@ class TestResourceMonitor(unittest.TestCase):
         monitor.stop()
 
         v = monitor.min_memory_available()
-        self.assertIsInstance(v, long)
+        self.assertIsInstance(v, int)
 
         v = monitor.max_memory_percent()
         self.assertIsInstance(v, float)
diff --git a/testing/mozbase/moztest/moztest/__init__.py b/testing/mozbase/moztest/moztest/__init__.py
index 5820ed2eb6..be7852c9df 100644
--- a/testing/mozbase/moztest/moztest/__init__.py
+++ b/testing/mozbase/moztest/moztest/__init__.py
@@ -2,6 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import adapters
+from . import adapters
 
 __all__ = ['adapters']
diff --git a/testing/mozbase/moztest/moztest/adapters/__init__.py b/testing/mozbase/moztest/moztest/adapters/__init__.py
index 46bb3c6eb6..c0c72fc22b 100644
--- a/testing/mozbase/moztest/moztest/adapters/__init__.py
+++ b/testing/mozbase/moztest/moztest/adapters/__init__.py
@@ -2,6 +2,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import unit
+from . import unit
 
 __all__ = ['unit']
diff --git a/testing/mozbase/moztest/moztest/adapters/unit.py b/testing/mozbase/moztest/moztest/adapters/unit.py
index cee0e05e92..3b27685b50 100644
--- a/testing/mozbase/moztest/moztest/adapters/unit.py
+++ b/testing/mozbase/moztest/moztest/adapters/unit.py
@@ -26,7 +26,7 @@ def get_test_class_name(test):
     passed in structured loggers. You can override the default by
     implementing a "get_test_class_name" method on you TestCase subclass.
     """
-    return "%s.%s" % (test.__class__.__module__,
+    return "{}.{}".format(test.__class__.__module__,
                       test.__class__.__name__)
 
 
diff --git a/testing/mozbase/moztest/moztest/output/autolog.py b/testing/mozbase/moztest/moztest/output/autolog.py
index b6c8368bd4..c5d5b77a2d 100644
--- a/testing/mozbase/moztest/moztest/output/autolog.py
+++ b/testing/mozbase/moztest/moztest/output/autolog.py
@@ -5,7 +5,7 @@
 
 from mozautolog import RESTfulAutologTestGroup
 
-from base import Output, count, long_name
+from .base import Output, count, long_name
 
 
 class AutologOutput(Output):
diff --git a/testing/mozbase/moztest/moztest/output/base.py b/testing/mozbase/moztest/moztest/output/base.py
index 7e39317fb1..9d0455a85e 100644
--- a/testing/mozbase/moztest/moztest/output/base.py
+++ b/testing/mozbase/moztest/moztest/output/base.py
@@ -3,7 +3,6 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-from __future__ import with_statement
 from contextlib import closing
 from StringIO import StringIO
 
@@ -13,8 +12,8 @@ except ImportError:
     # abc is python 2.6+
     # from https://github.com/mozilla/mozbase/blob/master/mozdevice/mozdevice/devicemanager.py
     def abstractmethod(method):
-        line = method.func_code.co_firstlineno
-        filename = method.func_code.co_filename
+        line = method.__code__.co_firstlineno
+        filename = method.__code__.co_filename
 
         def not_implemented(*args, **kwargs):
             raise NotImplementedError('Abstract method %s at File "%s", '
@@ -23,7 +22,7 @@ except ImportError:
         return not_implemented
 
 
-class Output(object):
+class Output:
     """ Abstract base class for outputting test results """
 
     @abstractmethod
@@ -49,5 +48,5 @@ def count(iterable):
 
 def long_name(test):
     if test.test_class:
-        return '%s.%s' % (test.test_class, test.name)
+        return '{}.{}'.format(test.test_class, test.name)
     return test.name
diff --git a/testing/mozbase/moztest/moztest/output/xunit.py b/testing/mozbase/moztest/moztest/output/xunit.py
index 0d0ef7bb4d..2189d15d75 100644
--- a/testing/mozbase/moztest/moztest/output/xunit.py
+++ b/testing/mozbase/moztest/moztest/output/xunit.py
@@ -5,7 +5,7 @@
 
 import xml.dom.minidom as dom
 
-from base import Output, count
+from .base import Output, count
 from moztest.results import TestResult
 
 
@@ -16,7 +16,7 @@ class XUnitOutput(Output):
         """ Writes the xUnit formatted results to the given file object """
 
         def _extract_xml(test_result, text='', result='Pass'):
-            if not isinstance(text, basestring):
+            if not isinstance(text, str):
                 text = '\n'.join(text)
 
             cls_name = test_result.test_class
@@ -86,7 +86,7 @@ class XUnitOutput(Output):
         for tr in results_collection.tests_with_result('PASS'):
             _extract_xml(tr, result='Pass')
 
-        for cls in classes.itervalues():
+        for cls in classes.values():
             assembly.appendChild(cls)
 
         doc.appendChild(assembly)
diff --git a/testing/mozbase/moztest/moztest/results.py b/testing/mozbase/moztest/moztest/results.py
index 435665c670..495cea578e 100644
--- a/testing/mozbase/moztest/moztest/results.py
+++ b/testing/mozbase/moztest/moztest/results.py
@@ -8,7 +8,7 @@ import os
 import mozinfo
 
 
-class TestContext(object):
+class TestContext:
     """ Stores context data about the test """
 
     attrs = ['hostname', 'arch', 'env', 'os', 'os_version', 'tree', 'revision',
@@ -31,7 +31,7 @@ class TestContext(object):
         self.buildtype = buildtype
 
     def __str__(self):
-        return '%s (%s, %s)' % (self.hostname, self.os, self.arch)
+        return '{} ({}, {})'.format(self.hostname, self.os, self.arch)
 
     def __repr__(self):
         return '<%s>' % self.__str__()
@@ -46,12 +46,12 @@ class TestContext(object):
         def get(attr):
             value = getattr(self, attr)
             if isinstance(value, dict):
-                value = frozenset(value.items())
+                value = frozenset(list(value.items()))
             return value
         return hash(frozenset([get(a) for a in self.attrs]))
 
 
-class TestResult(object):
+class TestResult:
     """ Stores test result data """
 
     FAIL_RESULTS = [
@@ -84,7 +84,7 @@ class TestResult(object):
 
         msg = "Result '%s' not in possible results: %s" %\
               (result_expected, ', '.join(self.POSSIBLE_RESULTS))
-        assert isinstance(name, basestring), "name has to be a string"
+        assert isinstance(name, str), "name has to be a string"
         assert result_expected in self.POSSIBLE_RESULTS, msg
 
         self.name = name
@@ -102,12 +102,12 @@ class TestResult(object):
 
     @property
     def test_name(self):
-        return '%s.py %s.%s' % (self.test_class.split('.')[0],
+        return '{}.py {}.{}'.format(self.test_class.split('.')[0],
                                 self.test_class,
                                 self.name)
 
     def __str__(self):
-        return '%s | %s (%s) | %s' % (self.result or 'PENDING',
+        return '{} | {} ({}) | {}'.format(self.result or 'PENDING',
                                       self.name, self.test_class, self.reason)
 
     def __repr__(self):
@@ -170,7 +170,7 @@ class TestResult(object):
             raise ValueError(msg)
 
         # use lists instead of multiline strings
-        if isinstance(output, basestring):
+        if isinstance(output, str):
             output = output.splitlines()
 
         self.time_end = time_end if time_end is not None else time.time()
@@ -206,7 +206,7 @@ class TestResultCollection(list):
             self.resultClass = resultClass
 
     def __str__(self):
-        return "%s (%.2fs)\n%s" % (self.suite_name, self.time_taken,
+        return "{} ({:.2f}s)\n{}".format(self.suite_name, self.time_taken,
                                    list.__str__(self))
 
     def subset(self, predicate):
diff --git a/testing/mozbase/mozversion/mozversion/mozversion.py b/testing/mozbase/mozversion/mozversion/mozversion.py
index 5dfcd306a9..598eb1b2f2 100644
--- a/testing/mozbase/mozversion/mozversion/mozversion.py
+++ b/testing/mozbase/mozversion/mozversion/mozversion.py
@@ -3,7 +3,7 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import argparse
-import ConfigParser
+import six.moves.configparser
 from StringIO import StringIO
 import os
 import re
@@ -15,13 +15,13 @@ import zipfile
 import mozfile
 import mozlog
 
-import errors
+from . import errors
 
 
 INI_DATA_MAPPING = (('application', 'App'), ('platform', 'Build'))
 
 
-class Version(object):
+class Version:
 
     def __init__(self):
         self._info = {}
@@ -38,7 +38,7 @@ class Version(object):
                 self._logger.warning('Unable to find %s' % config_file)
 
     def _parse_ini_file(self, fp, type, section):
-        config = ConfigParser.RawConfigParser()
+        config = six.moves.configparser.RawConfigParser()
         config.readfp(fp)
         name_map = {'codename': 'display_name',
                     'milestone': 'version',
@@ -46,7 +46,7 @@ class Version(object):
                     'sourcestamp': 'changeset'}
         for key, value in config.items(section):
             name = name_map.get(key, key).lower()
-            self._info['%s_%s' % (type, name)] = config.has_option(
+            self._info['{}_{}'.format(type, name)] = config.has_option(
                 section, key) and config.get(section, key) or None
 
         if not self._info.get('application_display_name'):
@@ -86,7 +86,7 @@ class LocalVersion(Version):
             # .exe extension
             if not os.path.exists(binary) and not os.path.exists(binary +
                                                                  '.exe'):
-                raise IOError('Binary path does not exist: %s' % binary)
+                raise OSError('Binary path does not exist: %s' % binary)
             path = os.path.dirname(os.path.realpath(binary))
         else:
             path = os.getcwd()
@@ -146,7 +146,7 @@ class B2GVersion(Version):
             with open(gaia_commit) as f:
                 changeset, date = f.read().splitlines()
                 self._info['gaia_changeset'] = re.match(
-                    '^\w{40}$', changeset) and changeset or None
+                    r'^\w{40}$', changeset) and changeset or None
                 self._info['gaia_date'] = date
         except KeyError:
             self._logger.warning(
@@ -163,7 +163,7 @@ class LocalB2GVersion(B2GVersion):
 
         if binary:
             if not os.path.exists(binary):
-                raise IOError('Binary path does not exist: %s' % binary)
+                raise OSError('Binary path does not exist: %s' % binary)
             path = os.path.dirname(binary)
         else:
             if os.path.exists(os.path.join(os.getcwd(), 'application.ini')):
@@ -241,8 +241,8 @@ class RemoteB2GVersion(B2GVersion):
             'ro.product.device': 'device_id'}
         for line in build_props.split('\n'):
             if not line.strip().startswith('#') and '=' in line:
-                key, value = [s.strip() for s in line.split('=', 1)]
-                if key in desired_props.keys():
+                key, value = (s.strip() for s in line.split('=', 1))
+                if key in list(desired_props.keys()):
                     self._info[desired_props[key]] = value
 
         if self._info.get('device_id', '').lower() == 'flame':
@@ -292,7 +292,7 @@ def get_version(binary=None, sources=None, dm_type=None, host=None,
 
     for (key, value) in sorted(version._info.items()):
         if value:
-            version._logger.info('%s: %s' % (key, value))
+            version._logger.info('{}: {}'.format(key, value))
 
     return version._info
 
diff --git a/testing/mozbase/mozversion/tests/test_b2g.py b/testing/mozbase/mozversion/tests/test_b2g.py
index 09e0eb09e9..9a2a151114 100644
--- a/testing/mozbase/mozversion/tests/test_b2g.py
+++ b/testing/mozbase/mozversion/tests/test_b2g.py
@@ -40,7 +40,7 @@ class SourcesTest(unittest.TestCase):
         app_zip = zipfile.ZipFile(zip_path, 'w')
         if revision or date:
             app_zip.writestr('resources/gaia_commit.txt',
-                             '%s\n%s' % (revision, date))
+                             '{}\n{}'.format(revision, date))
         app_zip.close()
 
     def test_gaia_commit(self):
diff --git a/testing/mozbase/setup_development.py b/testing/mozbase/setup_development.py
index c048d504f1..93d3aa26af 100755
--- a/testing/mozbase/setup_development.py
+++ b/testing/mozbase/setup_development.py
@@ -13,6 +13,7 @@ If no arguments are given, install all packages.
 See https://wiki.mozilla.org/Auto-tools/Projects/Mozbase
 """
 
+from __future__ import print_function
 import os
 import subprocess
 import sys
@@ -57,7 +58,7 @@ def info(directory):
         call([sys.executable, 'setup.py', 'egg_info'],
              cwd=directory, stdout=PIPE)
     except subprocess.CalledProcessError:
-        print "Error running setup.py in %s" % directory
+        print(("Error running setup.py in %s" % directory))
         raise
 
     # get the .egg-info directory
@@ -71,7 +72,7 @@ def info(directory):
     # read the package information
     pkg_info = os.path.join(egg_info, 'PKG-INFO')
     info_dict = {}
-    for line in file(pkg_info).readlines():
+    for line in open(pkg_info).readlines():
         if not line or line[0].isspace():
             continue  # XXX neglects description
         assert ':' in line
@@ -95,7 +96,7 @@ def get_dependencies(directory):
     requires = os.path.join(directory, egg_info, 'requires.txt')
     dependencies = []
     if os.path.exists(requires):
-        for line in file(requires):
+        for line in open(requires):
             line = line.strip()
             # in requires.txt file, a dependency is a non empty line
             # Also lines like [device] are sections to mark optional
@@ -180,7 +181,7 @@ def main(args=sys.argv[1:]):
     if options.list_dependencies:
         # list the package dependencies
         for package in packages:
-            print '%s: %s' % get_dependencies(os.path.join(here, package))
+            print(('%s: %s' % get_dependencies(os.path.join(here, package))))
         parser.exit()
 
     # gather dependencies
@@ -235,7 +236,7 @@ def main(args=sys.argv[1:]):
     if options.list:
         # list what will be installed
         for package in unrolled:
-            print package
+            print(package)
         parser.exit()
 
     # set up the packages for development
diff --git a/testing/mozbase/test.py b/testing/mozbase/test.py
index 013506fc64..2a329b461b 100755
--- a/testing/mozbase/test.py
+++ b/testing/mozbase/test.py
@@ -9,6 +9,7 @@ run mozbase tests from a manifest,
 by default https://github.com/mozilla/mozbase/blob/master/test-manifest.ini
 """
 
+from __future__ import print_function
 import imp
 import manifestparser
 import mozinfo
@@ -82,7 +83,7 @@ def main(args=sys.argv[1:]):
 
     if options.list_tests:
         # print test paths
-        print '\n'.join(tests)
+        print(('\n'.join(tests)))
         sys.exit(0)
 
     # create unittests
diff --git a/testing/mozbase/versioninfo.py b/testing/mozbase/versioninfo.py
index 82da432a4c..96803a4a0a 100755
--- a/testing/mozbase/versioninfo.py
+++ b/testing/mozbase/versioninfo.py
@@ -9,7 +9,8 @@ List mozbase package dependencies or generate changelogs
 from commit messages.
 """
 
-from collections import Iterable
+from __future__ import print_function
+from collections.abc import Iterable
 from distutils.version import StrictVersion
 import argparse
 import os
@@ -62,7 +63,7 @@ def changelog(args):
                         if StrictVersion(v) == plus_version:
                             return rev
 
-        print("Could not find %s revision for version %s." % (args.module, v or 'latest'))
+        print(("Could not find %s revision for version %s." % (args.module, v or 'latest')))
         sys.exit(1)
 
     from_ref = args.from_ref or get_version_rev()
@@ -83,8 +84,8 @@ def changelog(args):
         lines = [('* %s' if i == 0 else '  %s') % l for i, l in enumerate(lines)]
         return '\n'.join(lines)
 
-    changelog = map(prettify, changelog)
-    print '\n'.join(changelog)
+    changelog = list(map(prettify, changelog))
+    print('\n'.join(changelog))
 
 
 def dependencies(args):
@@ -100,8 +101,8 @@ def dependencies(args):
 
     # print package version information
     for value in info.values():
-        print '%s %s : %s' % (value['Name'], value['Version'],
-                              ', '.join(dependencies[value['Name']]))
+        print('%s %s : %s' % (value['Name'], value['Version'],
+                              ', '.join(dependencies[value['Name']])))
 
 
 def main(args=sys.argv[1:]):
diff --git a/testing/mozharness/examples/action_config_script.py b/testing/mozharness/examples/action_config_script.py
index e1135771e0..fc1cfba41c 100755
--- a/testing/mozharness/examples/action_config_script.py
+++ b/testing/mozharness/examples/action_config_script.py
@@ -4,6 +4,7 @@
 Demonstrate actions and config.
 """
 
+from __future__ import print_function
 import os
 import sys
 import time
@@ -68,11 +69,11 @@ class ActionsConfigExample(BaseScript):
             try:
                 time.sleep(interval)
             except:
-                print
+                print()
                 self.error("Impatient, are we?")
                 sys.exit(1)
             counter += interval
-        print
+        print()
         self.info("Ok, done.")
 
     def _ship1(self):
diff --git a/testing/mozharness/external_tools/clobberer.py b/testing/mozharness/external_tools/clobberer.py
index 300b2bc2f3..761ecfc6dc 100755
--- a/testing/mozharness/external_tools/clobberer.py
+++ b/testing/mozharness/external_tools/clobberer.py
@@ -1,8 +1,9 @@
 #!/usr/bin/python
+from __future__ import print_function
 import sys
 import shutil
-import urllib2
-import urllib
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
 import os
 import traceback
 import time
@@ -80,7 +81,7 @@ def rmdirRecursive(dir):
         return
 
     # Verify the directory is read/write/execute for the current user
-    os.chmod(dir, 0700)
+    os.chmod(dir, 0o700)
 
     for name in os.listdir(dir):
         full_name = os.path.join(dir, name)
@@ -91,14 +92,14 @@ def rmdirRecursive(dir):
                 # I think this is now redundant, but I don't have an NT
                 # machine to test on, so I'm going to leave it in place
                 # -warner
-                os.chmod(full_name, 0600)
+                os.chmod(full_name, 0o600)
 
         if os.path.isdir(full_name):
             rmdirRecursive(full_name)
         else:
             # Don't try to chmod links
             if not os.path.islink(full_name):
-                os.chmod(full_name, 0700)
+                os.chmod(full_name, 0o700)
             os.remove(full_name)
     os.rmdir(dir)
 
@@ -107,11 +108,11 @@ def do_clobber(dir, dryrun=False, skip=None):
     try:
         for f in os.listdir(dir):
             if skip is not None and f in skip:
-                print "Skipping", f
+                print("Skipping", f)
                 continue
             clobber_path = f + clobber_suffix
             if os.path.isfile(f):
-                print "Removing", f
+                print("Removing", f)
                 if not dryrun:
                     if os.path.exists(clobber_path):
                         os.unlink(clobber_path)
@@ -122,7 +123,7 @@ def do_clobber(dir, dryrun=False, skip=None):
                         shutil.move(f, clobber_path)
                         os.unlink(clobber_path)
             elif os.path.isdir(f):
-                print "Removing %s/" % f
+                print("Removing %s/" % f)
                 if not dryrun:
                     if os.path.exists(clobber_path):
                         rmdirRecursive(clobber_path)
@@ -133,21 +134,21 @@ def do_clobber(dir, dryrun=False, skip=None):
                         shutil.move(f, clobber_path)
                         rmdirRecursive(clobber_path)
     except:
-        print "Couldn't clobber properly, bailing out."
+        print("Couldn't clobber properly, bailing out.")
         sys.exit(1)
 
 
 def getClobberDates(clobberURL, branch, buildername, builddir, slave, master):
     params = dict(branch=branch, buildername=buildername,
                   builddir=builddir, slave=slave, master=master)
-    url = "%s?%s" % (clobberURL, urllib.urlencode(params))
-    print "Checking clobber URL: %s" % url
+    url = "%s?%s" % (clobberURL, six.moves.urllib.parse.urlencode(params))
+    print("Checking clobber URL: %s" % url)
     # The timeout arg was added to urlopen() at Python 2.6
     # Deprecate this test when esr17 reaches EOL
     if sys.version_info[:2] < (2, 6):
-        data = urllib2.urlopen(url).read().strip()
+        data = six.moves.urllib.request.urlopen(url).read().strip()
     else:
-        data = urllib2.urlopen(url, timeout=30).read().strip()
+        data = six.moves.urllib.request.urlopen(url, timeout=30).read().strip()
 
     retval = {}
     try:
@@ -160,8 +161,8 @@ def getClobberDates(clobberURL, branch, buildername, builddir, slave, master):
             retval[builddir] = (builder_time, who)
         return retval
     except ValueError:
-        print "Error parsing response from server"
-        print data
+        print("Error parsing response from server")
+        print(data)
         raise
 
 if __name__ == "__main__":
@@ -196,11 +197,11 @@ if __name__ == "__main__":
     except:
         if options.verbose:
             traceback.print_exc()
-        print "Error contacting server"
+        print("Error contacting server")
         sys.exit(1)
 
     if options.verbose:
-        print "Server gave us", server_clobber_dates
+        print("Server gave us", server_clobber_dates)
 
     now = int(time.time())
 
@@ -214,7 +215,7 @@ if __name__ == "__main__":
     for builddir, (server_clobber_date, who) in server_clobber_dates.items():
         builder_dir = os.path.join(root_dir, builddir)
         if not os.path.isdir(builder_dir):
-            print "%s doesn't exist, skipping" % builder_dir
+            print("%s doesn't exist, skipping" % builder_dir)
             continue
         os.chdir(builder_dir)
 
@@ -223,8 +224,8 @@ if __name__ == "__main__":
         clobber = False
         clobberType = None
 
-        print "%s:Our last clobber date: " % builddir, ts_to_str(our_clobber_date)
-        print "%s:Server clobber date:   " % builddir, ts_to_str(server_clobber_date)
+        print("%s:Our last clobber date: " % builddir, ts_to_str(our_clobber_date))
+        print("%s:Server clobber date:   " % builddir, ts_to_str(server_clobber_date))
 
         # If we don't have a last clobber date, then this is probably a fresh build.
         # We should only do a forced server clobber if we know when our last clobber
@@ -240,9 +241,9 @@ if __name__ == "__main__":
                 # We should also update our clobber date to match the server's
                 our_clobber_date = server_clobber_date
                 if who:
-                    print "%s:Server is forcing a clobber, initiated by %s" % (builddir, who)
+                    print("%s:Server is forcing a clobber, initiated by %s" % (builddir, who))
                 else:
-                    print "%s:Server is forcing a clobber" % builddir
+                    print("%s:Server is forcing a clobber" % builddir)
 
         if not clobber:
             # Disable periodic clobbers for builders that aren't my_builddir
@@ -264,11 +265,11 @@ if __name__ == "__main__":
                 clobberType = "periodic"
                 # Update our clobber date to now
                 our_clobber_date = now
-                print "%s:More than %s seconds have passed since our last clobber" % (builddir, periodicClobberTime)
+                print("%s:More than %s seconds have passed since our last clobber" % (builddir, periodicClobberTime))
 
         if clobber:
             # Finally, perform a clobber if we're supposed to
-            print "%s:Clobbering..." % builddir
+            print("%s:Clobbering..." % builddir)
             do_clobber(builder_dir, options.dryrun, options.skip)
             write_file(our_clobber_date, "last-clobber")
 
@@ -276,4 +277,4 @@ if __name__ == "__main__":
         # Note in the case of purged clobber, we output the clobber type even though no
         # clobber was performed this time.
         if clobberType and builddir == my_builddir:
-            print "TinderboxPrint: %s clobber" % clobberType
+            print("TinderboxPrint: %s clobber" % clobberType)
diff --git a/testing/mozharness/external_tools/count_and_reboot.py b/testing/mozharness/external_tools/count_and_reboot.py
index 9e8ae35a65..643ddc2c40 100755
--- a/testing/mozharness/external_tools/count_and_reboot.py
+++ b/testing/mozharness/external_tools/count_and_reboot.py
@@ -6,6 +6,7 @@
 Increments the value in countfile, and reboots the machine once the count
 reaches or exceeds maxcount."""
 
+from __future__ import print_function
 import os, sys, time
 
 if sys.platform in ('darwin', 'linux2'):
@@ -55,8 +56,8 @@ if __name__ == '__main__':
     if increment_count(options.countfile) >= options.maxcount:
         if options.zero:
             open(options.countfile, "w").write("0\n")
-        print "************************************************************************************************"
-        print "*********** END OF RUN - NOW DOING SCHEDULED REBOOT; FOLLOWING ERROR MESSAGE EXPECTED **********"
-        print "************************************************************************************************"
+        print("************************************************************************************************")
+        print("*********** END OF RUN - NOW DOING SCHEDULED REBOOT; FOLLOWING ERROR MESSAGE EXPECTED **********")
+        print("************************************************************************************************")
         sys.stdout.flush()
         reboot()
diff --git a/testing/mozharness/external_tools/detect_repo.py b/testing/mozharness/external_tools/detect_repo.py
index 67466a03e0..fbc8024653 100644
--- a/testing/mozharness/external_tools/detect_repo.py
+++ b/testing/mozharness/external_tools/detect_repo.py
@@ -2,20 +2,20 @@
 # Stolen from taskcluster-vcs
 # https://github.com/taskcluster/taskcluster-vcs/blob/master/src/vcs/detect_remote.js
 
-from urllib2 import Request, urlopen
-from urlparse import urlsplit, urlunsplit
+from urllib.request import Request, urlopen
+from urllib.parse import urlsplit, urlunsplit
 from os.path import exists, join
 
 def first(seq):
-    return next(iter(filter(lambda x: x, seq)), '')
+    return next(iter([x for x in seq if x]), '')
 
 def all_first(*sequences):
-    return map(lambda x: first(x), sequences)
+    return [first(x) for x in sequences]
 
 # http://codereview.stackexchange.com/questions/13027/joining-url-path-components-intelligently
 # I wonder why this is not a builtin feature in Python
 def urljoin(*parts):
-    schemes, netlocs, paths, queries, fragments = zip(*(urlsplit(part) for part in parts))
+    schemes, netlocs, paths, queries, fragments = list(zip(*(urlsplit(part) for part in parts)))
     scheme, netloc, query, fragment = all_first(schemes, netlocs, queries, fragments)
     path = '/'.join(p.strip('/') for p in paths if p)
     return urlunsplit((scheme, netloc, path, query, fragment))
diff --git a/testing/mozharness/external_tools/download_file.py b/testing/mozharness/external_tools/download_file.py
index 91b0a46685..bd149fd185 100755
--- a/testing/mozharness/external_tools/download_file.py
+++ b/testing/mozharness/external_tools/download_file.py
@@ -9,17 +9,18 @@
 We lose some mozharness functionality by splitting this out, but we gain output_timeout.
 """
 
+from __future__ import print_function
 import os
 import socket
 import sys
-import urllib2
-import urlparse
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
+import six.moves.urllib.parse
 
 
 def download_file(url, file_name):
     try:
         f_length = None
-        f = urllib2.urlopen(url, timeout=30)
+        f = six.moves.urllib.request.urlopen(url, timeout=30)
         if f.info().get('content-length') is not None:
             f_length = int(f.info()['content-length'])
             got_length = 0
@@ -28,42 +29,42 @@ def download_file(url, file_name):
             block = f.read(1024 ** 2)
             if not block:
                 if f_length is not None and got_length != f_length:
-                    raise urllib2.URLError("Download incomplete; content-length was %d, but only received %d" % (f_length, got_length))
+                    raise six.moves.urllib.error.URLError("Download incomplete; content-length was %d, but only received %d" % (f_length, got_length))
                 break
             local_file.write(block)
             if f_length is not None:
                 got_length += len(block)
         local_file.close()
-        print "%s downloaded to %s" % (url, file_name)
-    except urllib2.HTTPError, e:
-        print "Warning: Server returned status %s %s for %s" % (str(e.code), str(e), url)
+        print("%s downloaded to %s" % (url, file_name))
+    except six.moves.urllib.error.HTTPError as e:
+        print("Warning: Server returned status %s %s for %s" % (str(e.code), str(e), url))
         raise
-    except urllib2.URLError, e:
-        print "URL Error: %s" % url
-        remote_host = urlparse.urlsplit(url)[1]
+    except six.moves.urllib.error.URLError as e:
+        print("URL Error: %s" % url)
+        remote_host = six.moves.urllib.parse.urlsplit(url)[1]
         if remote_host:
             os.system("nslookup %s" % remote_host)
         raise
-    except socket.timeout, e:
-        print "Timed out accessing %s: %s" % (url, str(e))
+    except socket.timeout as e:
+        print("Timed out accessing %s: %s" % (url, str(e)))
         raise
-    except socket.error, e:
-        print "Socket error when accessing %s: %s" % (url, str(e))
+    except socket.error as e:
+        print("Socket error when accessing %s: %s" % (url, str(e)))
         raise
 
 if __name__ == '__main__':
     if len(sys.argv) != 3:
         if len(sys.argv) != 2:
-            print "Usage: download_file.py URL [FILENAME]"
+            print("Usage: download_file.py URL [FILENAME]")
             sys.exit(-1)
-        parts = urlparse.urlparse(sys.argv[1])
+        parts = six.moves.urllib.parse.urlparse(sys.argv[1])
         file_name = parts[2].split('/')[-1]
     else:
         file_name = sys.argv[2]
     if os.path.exists(file_name):
-        print "%s exists; removing" % file_name
+        print("%s exists; removing" % file_name)
         os.remove(file_name)
     if os.path.exists(file_name):
-        print "%s still exists; exiting"
+        print("%s still exists; exiting")
         sys.exit(-1)
     download_file(sys.argv[1], file_name)
diff --git a/testing/mozharness/external_tools/extract_and_run_command.py b/testing/mozharness/external_tools/extract_and_run_command.py
index ab48ee1dff..828f95cca7 100644
--- a/testing/mozharness/external_tools/extract_and_run_command.py
+++ b/testing/mozharness/external_tools/extract_and_run_command.py
@@ -20,7 +20,7 @@ import logging
 import os
 from os import path
 import sys
-from Queue import Queue
+from queue import Queue
 import shutil
 import subprocess
 import tempfile
@@ -75,7 +75,7 @@ def find_files(d):
             yield path.abspath(path.join(root, f))
 
 
-def rchmod(d, mode=0755):
+def rchmod(d, mode=0o755):
     """chmods everything in `d' to `mode', including `d' itself"""
     os.chmod(d, mode)
     for root, dirs, files in os.walk(d):
@@ -90,7 +90,7 @@ def maybe_extract(filename):
        directory and chmods it. The consumer is responsible for removing
        the extracted files, if desired."""
     ext = path.splitext(filename)[1]
-    if ext not in EXTRACTORS.keys():
+    if ext not in list(EXTRACTORS.keys()):
         return None
     # Append the full filepath to the tempdir
     tempdir_root = tempfile.mkdtemp()
diff --git a/testing/mozharness/external_tools/gittool.py b/testing/mozharness/external_tools/gittool.py
index 520aeaf38e..1324f39c43 100755
--- a/testing/mozharness/external_tools/gittool.py
+++ b/testing/mozharness/external_tools/gittool.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 ### Compressed module sources ###
+from __future__ import print_function
 module_sources = [('util', 'eJxlkMEKgzAQRO/5isWTQhFaSg8Ff6LnQknM2ixoItmov1+T2FLb3DY7mZkXGkbnAxjJpiclKI+K\nrOSWSAihsQM28sjBk32WXF0FrKe4YZi8hWAwrZMDuC5fJC1wkaQ+K7eIOqpXm1rTEzmU1ZahLuc/\ncwYlGS9nQNs6jfoACwUDQVIf/RdDAXmULYK0Gpo1aXAz6l3sG6VWJ/nIdjHdx45jWTR3W3xVSKTT\n8NuEE9a+DMzomZz9QOencdyDJ7LvH6zEC9SEeBQ=\n'), ('util.file', 'eJzNVk2P2zYQvftXTF0sLC9ctTbaSwAfim2BFCjSIsktCLy0SFnMSqRAUuv1v+8MP0RZ3uTQU3Sw\nJXLmcWbem5GWy+Vb0fbCQD2oykmtLDgNDVO8FVBL/NG4y/zOcrlcyK7XxkGrTyepTulR23Rnm8HJ\nNj01zDatPKZHJ7qeMBe10R08aFXL07/MWDw+Wrxn5+nyAs+BfTqtPAn3N94KUxwOinXicFgvFgsu\naqh01zMjCkLfbnzgu/WbBeCFUcddTK0RaKqcUM6CrsGdtbe1G+iZtYKDVCAkmhlg1rvjhRVQoRah\nLuiK21UlrJXHVKaeucaW8IfGbQYW88E8I4Bi8lmAdQaTiKFKq9UGrAauQWkHg8VKK2iZOREZFBOV\nm7xlDdJKZR1T1ZjhkVkRAGOadPk9rBcFnAxXZrWBj2YQ66+A7b4BtpuC7W7A/BGHsaD7sFAawXiR\nLXZzi93Uwgg3GHUDtZ+5Rp65NKJy2lxQJY5hHsW4gtUc6lq+ZNrhfcB2GDAlTuyfkAmVYbwaCMdv\n9kY/S44qOMuWV8xwjxRgN8SpRH6oPx5bC7XWP98fmXmERFQjHWbI1KX4VJdCcXtGJRUxKrRHXklf\n2pattA5jyMGvP4/0kBoQKROB6i+FMdoUywc9tNxb1FJxuL+zBHhnl3AHRYozg15VGDHHZukvVN3C\nmgrNrdv4pU5zsffkjhV8wGVAK8rZ2/XYRcI8k45xLHQSO4BGBrYFONmh9GU9YqHQvFZSecJoKG9O\nHzNPjjn1iQttzFxmFqhpN7EIudqGbe3QFXVOKqkCCf/w9veftn5K+Wkwmw6+rx/rxw0VuREvRGHH\n3Eg3kh0HXEnHJMn3Y9NQwxxXYfncEBrVI6d3bHX1RE3Rh474bbuDe9j+svs1JxgV4U2zp/dGn6dx\npSmHnjMnCm95zXyJwXN5wh4vxrqwWhwG1Ur15JubxmkuUdiAtAHypLRRxLoXok3d5CvEceSplQPx\ngqpOxXHm8maaA4qeJmQpLel+duI4crBFjNbOa9iGMW5jy5xZmyPdoCB7rs9qqtc5km82D3G7n4mK\ncX3RUhXh7Hr9qvlVxfpbG0QyHSVHKHlbtFZcnz+phi+Z/Vo5IuqcJW8jXirRO/jnw59EyAYmZ/wI\nfxFdApbvNA6vqonvcZMnw3JKjaDpojTN3N11AEE/30jFMGnFVFGz5kbFZVGRQXvxXT7OFDTAVx8J\ni/mvA20YDmWJPWg6wSXqOcyWBoe2ofTpo4PwonOSW81REl3vxbofvzPK7snSPc3Zfao53pNZ4YNb\nvzaZ9PFL4RvYJ+FbeENE1Dy0NZ61OuPijXOeQDGWYEHK8NQVcTlWJhau1YzTew6/euZKCKuY0ey7\nqJjMTFoN4+NT8v68hh/2kB8zaXEivNNKTCdEQInx4FdWCif84atP+G9DrEIf/tGODW0iN8eB8/AQ\njYv4v/YMTvYDRjHDXN8EGV0wnBvbaewxlJvgD6ii7yUBCuV/5XDUuv1ekqBYBLt1eS2R/wBE3uXX\n'), ('util.commands', 'eJzdWW1v2zgS/u5fwXPQs9x1laDFvSBA9pDdJnfBtkkucS9XtIEgS+OYG4n0kVRc76+/GZKSKPkl\n2T3slzPQOhLJ4bw888yQHg6H55XIDJdCs7lUTFVCcPHAMlmWqcj1cDgc8HIplWG6mi2VzEDr+o1s\n/jK8hPrvZZEaFFXWz4V8eECRA/xmJ/VT/ADmA/4JKkoSkZaQJOPBwKj18YDhxy9dcfHu7ZwXsPEy\nXXL77vrz3cXlu7coeKoqGMC3DJaGXdiZZ0pJddybdp4WGgaDQQ5z0iXJyjzCfxP2+vXjKlUPeuxW\nHLBslTOumV5CxtOCccHMIsXtgaXFKl1rtkqFYRwNVlwYQBHwBILxOb4baSak8YLg27LgGTfFmmUL\nqUHY92431Mj9EWdyuY7GztA5G+HuI5JB+7oZTq926Rc75x4lSE3uxCe/Hu2KuZjLaOjDeMxup6c3\n0+HO4Vd6yF4FEY4Lrs1b9EvBBZB/xm4pQeQR1hP2lBYVtLrF3IDCf6WOxq2eWzeym02cFG1UZCWh\neBeSEtQDJCCeIvznRQlY0RtnKP7BlRShu/x4XC3z1IBdaN8rMJUS9bDfAAG+M+YI9ptKMBxiUcrI\nBUzOGU6oShBGj2PGblKuIXTUj2lRQH7tniziMHxWmllAnUYIAW4QMNwsMKbizS+gJAq7mHcmOX0R\ncVVGwuZVUawnoSVHMaWj9+wWKzze7oA5V6B0BHA6x9jUecdmkKUVmoAwzqUYGYdiNIJMJW24WNhQ\n5jV60fNPqdKsrHKCwwMKtxNlZZaVaQCL80b7wErjBNY2wp0Rp3xDAPYBZxOxxPSfj/UOWDldjoft\nJO+yIFLZArLHJENTt7nNM8feyG5B9qhR4ezm5upmNCFBCQ2dECEF+hBwXA5xgZIDO6FIlxryrrXs\nDTP7LD67fM+iV/Hbua7Xj78KzKv6IYD7fyoOZifoc3gSiDTKriWICFPMv5mw0WrUyaQ9ztQmxxic\nNEvxGZRqn1tnt3opKKWBVjEN6gnUhCE8FZWEk0spAF/rxU+wbh9ORvjfaNI4J/j0TEOpyVLBnH9D\n677gqvsarfUWbRDauTF8MyDy6MvoTTFqtblvuNkp9MxSjkvRl8vULPDtEmNGgiK3duyFBSvT5ZJW\nOh80W3HNhTapyMC5aJZqQNLELBx39if78Os+jFbAdLUXvmM95Hc4MVli4sucZ8lS1nHFedQPJFTh\nFFL1ybujowmj8fbVUfz2T1vD4T+1DELLLM0efSh/JfkSt6QBBBlRpoUhI27FxFgWQI2MlVabQpn2\nYtrepGwr67fQdkvZg20uYHPfdaFwzL0ZSrMKub1I+hxdLFdEt40LvIYOOW5z7DPgG2SVFWXSR9DI\nFQK7KpooNqLXYgZBpUxCVNNQBoYV3VHH4v+6zDxbQcgTKCQAzLVlxy2OaD25pVwVqUbmtSA9CWYO\nHCgW2NnavrU1Q9G2tGdsc3A8aEbQeBzktrFklEHHnZQjk3KYVQ/R0KPaQxBBZRsulY07C5y8kxN2\ndLyRu7sqUmBBf8lvKVF9GXXOdAYA+/VNDdXzCR2pbEJ0EvhQyNWOngK9QYNvwoh9vyd/6HOACmsw\n4RIjWfokeY6nhrQs7UHKZ3w3WCEscN+ewbXznUY7nI4a91ll000BKshBpNBOKqLGPHqlx3gS2EPm\nUX/9JFBwvBnTTkcXfvpyop2UtCnUN2tn9otU37oDGQ8WCdZ4a6zFTY61w8vAxRPGH4SkmhrH8XBf\nIfNbb2vv7NBWpJIW3lbUoykuNWljQiNvU2Aa4k7FcK8Swz4sMcvy8TNrJvWeWyDwzNJbCgw5zRBE\nmuDgA+U2HRyjvkbPefH5T4CG/1lWTTgBE1gO0AXAMuo0M3VLhOfpxJUEx/lcZEWVQ+L7WnuLMKHS\nZhIMcP38a1uatn0ISp3rMLobuvKHPQaYurduOgc/M3c3FLUU7D7xQa2IJrlpJmvcGFmqPaASbSps\nI7xQbC4hLWPnqDsXVXfvsZYV0wtZFTmVc6rttuw3jQxSX5Yu0RbANq1AI/G7lJUgm600pxeLvsfx\nOaxwuaw0eWC2NqDHk0bNHNK8kNljc9rlfXeEfYxVu1Oqb6fvrz5N3amuk5LNZCqfg+c6nN/nUOu9\ncMKGbdbtOuju7UL8iSscvLg+a05e7uv53OnaXO+KjMVNoEmjtR10W8eIlLxbQu2oA3Qmc2B/2Ogu\nXlK3e1J8EQ+2oQ6oTr3NLujZq4HORDe8cW8QdJ0vuRlAUmwVOWAfsRPHBQpc6njvufxl0qVpU7za\ne4C4cXOwfeu13+X6YP/tAZ7QnyChQ2xE/7W8NqXcp64f5yyLNANiNHs9qBdYZIpYlcgk3v6VVI8a\n2cfQCaESCEx/rhK5XOmYTbHk4QRkkB8gVVhnrIOubk/PrUR32MrBHaWiHyR6fIUGz5Us2aziRT6T\nBsk8fYK4vrceB0eYugO6IWuIz2w/bO0Z1JmecJ14fbbfYH7StDJxZtVTGXUMLXZ6o85lPWQ1OxKI\n2wsCrA06dLHDkfUyOicv8GA3U/IRz3TYxD3qMBtqIVzTUF8IfXCGi+R+jfYLeomQA/YvPNTN1zZk\nOVeQGanWhBPiisMVHfgOXR8CbWgrpQg8dD8y8Dtli1LmdqMJO/rL0ZEPFC2huxiiZOkuqXGXvqZ0\nAre/KbgbY2vTz5ILL49GxoGTMR/vXMAmtqmuT6wLxBOzKtNtQsm1tud1qpk07JwRyLGndjzRHbaG\nA6cajJwsmS/yxAaiFz2n6gkbCTPqBq6FSWrvFqLGNHu5dJdc/TTe7DgP2AXVZvHoKrQ9Mq5Q3xxT\nD0/hE8wZg1MCK7EdvpxukVOmGcoBykws0aS6teViVLIHaTsDyQogCdz+UGGZYIucN9Qf+uj2gOki\nHdh19Ocm3Bu4pGA3U3uWh1zVzglYst+cH7D31gNYnm3zQor0sqsbgzA5dmmx0yoL4t4sn089bWmg\nbGCNTHwQspPtGfs0RDc/AudZRizlLwtyt9aOxLdQm15rAyWVc/9bXezetL8/+RkY02joswM5c/iR\nZ0pqOTfDwG5fMu0PcJ3lsW3iNd1p4dHn89/vLi6fWbczG8K53qxtZNvUpzql39if7+Y8Y2FBqimV\n1iCAxYNZ6PD8xT6e/ju5Pp3+I24UuJb2DGQ9nBVyNgMFKl6u486FWaqRxEzX5e5CiXZq6QjpsGir\nquM2QoGfNvqKn799/Tpi39mVe2pGs2zDseEi//vncZhWXVRv4dHA7/Vd8iiHgh2es8N/siFW0RGe\n/brVYDPN+hIsttnh7XYZYe/UKSBExOnM/xLc/C4c34I5x+9TYxRHWgN9F/WdNwmmn198OEtOp9Ob\nix8+Tc+Sy6ubj6cf6p1v8ZABjuDxFOLwgp2UvZJNLbUT+5VAHZbeFhLnxf7+m4hv9XkPBRggCzaX\ntSVvPkdHUC7WP33H5wguWqU3luEXvnodvx6FFRGnJin6CLFlhX05um8vxVyldO//et+BSJ2L8YjV\npdc+xr1ClWE3zkXVcv+LanC4VaviH3fH6/3FzdmP06ubz93d+1TwIvp/MYYCFn8RkDY32BHlnprt\nfNuowvsa/lug8V+mJBic\n'), ('util.retry', 'eJytVk2P2zYQvetXDFwsLDuC4C2wORhxsUHQFgWKnHqXaYmyiUqkQ1LxGkX/e2dIivpy0h6qw1oa\nDh9nHt/MjmivSluwouVJrVULdSdLq1RjQPilm2ZX49dKJS1/s4049YvB0jLJzlwnwdqo81nIc4K/\ncOi/8jO3v+Mr12lRSNbyotgkSVLxGjS3+p6y0golM2DW8vZqzeElA9NwfqXgDu93GbTsrRgsL7AF\ntCYQH4dT8LeSPJQ0h/Tn/j3bZFA2nMnuevisJMdj9Bkd0Pznzb3+9fdm77BWq9Un1jRw9AGtgdHB\nou1aUDVaQ3hrR5qBTlrRgLBgurLkvDJDRJgb6xqLyYNV8JLDMUa/BmHAXjjIrj1xTciGI5uVIdcb\nEzainLi9cS4jL9kM9/0OmKygUt2pIRNn5cVT0W/J0C3CTbOZULrOAY5zEl2kDGx3bThuiTiRWsqD\nYfoX1TUVRgsl684Xm8NvNQwwoDBbTa4S/yjDI1AjjOUVCPnobKY5aCYMOjgJ9peSEXl3uAm8qNOA\nFVxF2/JKMMubuwvjGK7e5XLV6quo0ItYK/Gm2QkzwwsksBHrbm0KBqy2mASmELMnxD7hz4pU1bVc\nWhOBQohwZYZCwwsTnpu76nSvSV92BKf5l05o1NUSCUPEwzTKBCOSlIEjHnFckbp1ScH1WxtuTETO\nI86R9L526R+9+D3P/SU7NYnSkkBiFBQ4pQBY8YOY0HjsKVxj4bgFSpR6Q7CHwt6M16SyMXWlB9dg\n876inlY8fBj6wX6QjzrnFT9153Q19X6qwBHgJDc2r+AJ0lHbgOkxo66z8YFI7GLP7u12EUiQhA+H\nWI5DJKjd/QSWQhOyVunKCXsP1FeoRJ8MysJeXA/a41ffhPz7agISn1U4EX4IKfQN01id0u6Nf/VQ\n+CFD+LE4uO00qsNtS7fklcF2G/yjqy+/RTNdphZYj7lREQwVv4dVRl8FMXD4Q3d8Gg3ebrjt/SLf\nsJAuduBNPGL+m4T/Kr4S36QyidwSbWM1Ttih1jE/b5DNT7D7D+f9wlAfVVCQu+kq9vUTrxV1M/LE\nJYzl8T3TMyhw4UPW3K2n3/EaAj+M3rfw48JzluWkFJYZz7En7hNvGg2E7AZjLSTKf1YiEt5RbQ1z\ngHB9YOvV10vUfwWheoD1eg0f8T9hqTSz2EKQ2zBHbHLszqylTtYZHEu8/+sA7tmiA2ulRhrL8zyZ\n+8Zh5Hm3G48jz7sB5cR0utlPYEKESfQpImRRowIVxkmNebTt1Q1a3jqeIMZbyeWKA9S8dveP6tyz\nQXhh2PGbwrjjfxBjxPS39Ti7gmR21DLE5PFqyB3v+3U2OsY5EEsjBP3vIlhwFlEKYb/D0v/M0CN2\n7oLjNNTHkvwDPQB6iA==\n'), ('util.git', 'eJzNW+uT27YR/66/ApF7IymWeEk/Xuam4/iReJrGntiZdMZ2JEoEJcQUIRPgyddM/vfuAyDAh+S7\nNkmrGVsiCSx2F7u/fRA3Ho+f1eXGKl0aketKqNLKKoUb5VYcld2J3XY8Ho/U/qArK7Txv0y9PlR6\nI01zp66KQ1oZGV0Xau2vKjka5ZXei9qqItno/T4tMyP807pcbvbZHIbt9Y1cHlK7m9PdD7WSFp9F\ns3NVSD/TpLlc1mWhyvcjv1aht1vgfwTf4tpfJVtpv4Ofspoul2W6l8vlbDQabYrUGPFE5mld2Fe7\ntJJfp0ZejQR8DvBo1H0EFLu3pkgok7lY7tP3cpmujS5qK6eVPOgZk1K5wKvE2LSyBhU7HaMYV5eX\nYzcEPw/EP4CCcE9QhUZ4cs0gVA5wgfTeFLKMCb1rBuFTGOSfXZixuIDtS3ByAiTxe4r/zWiKLIDD\nMRIRpbZgBUTgqkuuS4AkHPEAW1c8yykD9L3ES1J2rIu1sgZoeXtJUMpDoWxEbaeN5SFgQsmHWoM2\ncVpSSlvozVyMx7NRpIv+QGKzMLZSh+kYVBOmOE69KL9oVU5xvblgdTD3u9QA9zfKgGdMM4mP/aUT\nA9ziByJlxOuqlrzFPELIj8qAkKBGnIoOhDNsdRtpNDbu6ZvJVtnJXEzAWvFrsdAl7Ekp6aL8chKW\nfzcXm2N2jYRn0f6QUMgI7+fHjTzEXpo8TotCZi/56mlV6eqqO/tZWoD7xvLnjeg57uI5yWlAR/DE\nKZyfbdJSrKVIxbpKy81OANrYdCvwWXIfFZmdPi6AKKkmmzTc/TmKUSVYKmtlDf5/Tc+CYp7DY5UW\n6l8SPBcMYX+wt+QVRlld3YrUsmbE85x+eI0BGgplyonlKXOhLOBvUaDGGBQz1ibMW+HCKxhOYs2F\n3ckS1Qp32VH9xE0lUwsTvXZho9C7vekrk6mKZIkgCAwwUWWup2NaFuMAgMdctNUawe40PJGFh078\nYDhBfeF6BQg5sBgNi3CFnJGVm89ao06x1RkGEralyzur8a42QWbamd+WYEhamEDPH4hv/BbloOb3\nQtcWl4ebADqw+1Y7/XNM3ctM4QUwJTdgCjgENORoscxoBLSZ8N8tW0YifmLP2SHhHez5EQccagA8\n0AFodw+hSB0K3nrj6MF9AFe07AIZMRiqMjYOFBu424ElbnRpUxiK4VjTDFnamENH7TtpJ8ZLA0SR\nv7YgqjK278CwFRgRYaSJrYRd8MUrcra5iBQO+pOJrKoSgs21+OsX7a14IL4H602blUFFSCFJEgBL\noXNii4UweEn+xU6Vdgg1JFr3q1ShnztO0J8CAwBBYKgNCCEMMFDjMPr1YcJe8m7AF07NDnNGbSsX\nY3YGmDhzcauFhnjfI5JZAlmKtbF/DaC0Uwio8AYgKhMwjWziPvjQhsTeliOqgqQRvr7UB0hS3oxh\nMfBXcN+bBcV9vFgs4O4CVhlH4D0XgBXgTdcxkecvn85iM8EHyTEFLJ6Jz65Fx1JaTDbWWNtDjWkF\nzeU1ErDpbDpLOFEIK6BCga0Imkpd7QkxBrCKKc9aUQc0DLOnDaFr1j5gYnRrgNY4QUXNehGMSf4+\nMQxTM8fFCYthT4LcCsADf6OlBLdDZOco9gx+NXHHMEAphg02Nmtkkc9pRiW3dZFW7aE07JJkdkYI\nSbesbN+qRwN+BACWK5cwrbUu+BeIxw8rmZB3skeeMk0qPO5mfJHVscOYJUn/SZtSeRiLWTluxjjs\nUTYcA50tDOAJTsAxscY8Ac4oplkr3c3c1hvYeooGlG3POTK4/U8LiFMlYLzpshMbDGXpoF69/gXM\nwTCc5Rq/A4EJL07Ul27kOaLMRkTVRVkqQWmXAm0YdZzMQGqRR8lGcqwUJP/jC/O2xFqntbSHyk0h\n0zKuRR6I10cNNpNDfNvDMyPGNAatZK+zupCYZBx3CvJVir0QNY9SHFOIk0aLPK2SBpxbSSpRIXPM\no/+zicM5p/wTpsbMplm2xFTF+r3iC6qnmotIFnCgR1mG6M7PKLPOxCqatvL+DEUU4JPHf0wXVvhj\nxVYOu0MNABi8itZZeRftScuDyAQyzsiHOY2kn0UG6UZAFXdnSV9JyygFkwhdvNR34BGWXMC0+/G5\nbfjs8ziMn54zxs8bWbopcwwC32PKojhlcduVaYm5ioN4FerGDugFQRY3d4W28/Y2BG3IORaglEp2\nwA3vm2mUFOypHwHJnt3sphX6oHk4ffvq4Uy8neYSbr6d/QWdEsZIs0kPqMOgvTkt1Arv+8F4vk+2\nla4P0y/7xnM/wznvIIM2j6lZJtf1FiHmCs2BXISHIkiE7sX+1jEFWjlrNj40RBOuY667QXzUnwCg\nhCkbmtNQDYesmharUDahjPD/9AgQemFmjvfTypuH9aIK8F5+OxDC2kwCbrR5vDCf5Cswc3eo9N7s\n2k1z0WpwXKMeQ6vFXdaHDOLOEkdeU8UdlOBbgNfdniDoTGEeZhwNigdMotMxwI6fAdeF1ICKshUO\noup+B/uz8rysEDVWjs+V2OzkBiorqjqxM0rUGMMTNpMnmsMV1o20BOw6VmO8yi49AEDMwbs3RU2q\nh6TMqHVxC6zq9VpW2EGlVIMaOU3vwYlFDIINzLkEttjagOq1NpIgzY0Sawk4IhvGnMiNHTf6Q2rD\nTdiWmjmFkOWNqnSJHd3p+Jvnr5evvn30w9Pl149ePV0+ef4D2A3qfDa8St9bmiZl466tpmWbi05V\nQImMCZvezB2y+JgAstBmkB5EDJI+qRkbZcLNyMGODVXouJehFURuFGY1k1pFG7GBfa1moGtuobW3\nGyQgeG0V6CYaytr2I1x18pS+wHDbyyCzx7QqgUvgV9dFhuW5ay3EbYoL8xVUHCZdU58Dn8B3LMsc\nV1qi4ANsxhZDqu497O0D1Sv9FjfXHp3q/DF6H/JFkzr9MVdFnyjL3Yhust7vi7U0BYDo0gOBjgtV\nFHgzNVNDJd/UZ19FLtzr3LHFhwZYJN85a+x2YkKf06UwsGVosAAJgJd0j+j0bazPTqhJXAXWN9d+\nX+6BeAGLVEcFewziUqICOmmKIv+hZ4NY774DUrvvNuAzWvueH72eIazWdcWMopbijJnUobY7Kw5F\nupFnfTx24s37Jb3Y+lSVRIqB2lCVmfyY4Lzx7IxlNYQHzGuooRrGt/coaoEODDmzhU5zEDuOEnJX\n0N4BQg24OVsw6dqpLm0i75wDHMpzlI7CLr1xwat5z5IWmI7eUjfd6HnTPIWaH5UsSknrOAKUiYKV\n3todvhBkr9dLvn0ddYviVzmwW+2deoAFYKbRFYmjwLQwB7lRuZKQdENxiD1azJ7ljax4yVC+h1XD\nmwl8Bdd97dJ648Srx5ylG1unBcRsZCIXbM6wNHDoRMc6iAWPSPhMgAz56PbAO3L+aS7RfD/9gmxI\nWdT1CZtsmi1ym6PsydX9zvj7V4OY1QWJZ0QCnRUkM4wRjeu2xvYiIhN4/eLJiyvxLWAb+CYtzHkq\nYYeByuU9Kc1c2nRrLv8Jnx6R6P1Yz5riD1GP+zIc5jrwNOvNHX5pcXeKPUjsvBO5V7sxaO6V3ksy\ne7CB0oojpGzbzwbGPeZgFSEkBpJKLrgd350QgIu6/2FPaG8hUC7a4W8gmvhPHAfPDQuvBfxn0Fju\nt8/Rfrg3XnjblTHXYw0xRJXj++/23ej+IXseZaLNDpzMQO+5Cffd9n6a0V3sxIj2Zve1Pbj1saOx\n1v8jHzuRNP+P5AcXhmyOsRONh1u6oaHBgk7Yoia+A+JxOkqihmqVH33c51bkRh9uvYquKPn3UeLK\ntwJyX827KBMFGYIahXgcOSAe34HYAhE4NVGUjsNGs0Y7Tf10hCOIagdrp4fLCzOhTlcvFg7owLCD\nIIM+fgO/xkJSgy8wPZHxkNRhS3NXvPYkDENcyhDXO+4Bnp6hnZqeyI6bZkifBZVHfY22oNxpHzyL\nAXQaIxmaHk/1bftTOTw3V9qtFq4iOXHvN29C4+UxUjWhCY5bSim7wZ5J04khu4bbFMgg+8R0jmDB\nv+iifDMR4jWkT0ddUV1I5uyPYdCJjju3ULiYodNu/U4K94NhBC5CY1o9H6TO4nePh6CUUXltGuZq\n8JEwOdIWUXBKJBKQTw+K506ZNM0dt7XnK9wTJSj2NlngIcx4ZC3q0lULkaLcnChaYvua79IZiS7N\nNt3HsUIJbXhC29kGgb9508s2yvM6Vto2wuj3kDN3X/b6j4sQf5e3a51W2XM8U1LVBzvAUi9tult0\nkf7xdAxhfl3IfdvSnDpP6gc/eKJElXVYvh8/g9pfukMs8RaKPIXCMvsKvvnhOoUy0OrQD3aW0n0T\njOp3RyrexW2YwTDk0/ofwYv5BMflYuHkQ2/+WwCjfZZQqzSbThaLUi+oLtW1nQSL9WGrNUl+tDjp\nDb6ZpvNu0UG1TmsyuzqxHD+dBIkbqgEL34XTIc25EEd8UHRnYdzojIKbx9rBYDDYFo967CFdbdCV\n4jtAaQsyXG+b37G4Tja3tV2TOyEYKqVCUPUAiz0lX9kPQxAznTVvN3HlqE2gaSorsa7okJNbHtb7\njvOPXVpuZYDFTJkNuFl0eM61MLpFP8Sbo8Iak9ZOrRv7EyFrM+rnL8SUqxpaFi7XstDHGVW+utpw\n8c0lJfVFHJkMjDGHf+WGMhlEPb3fA5arzPj30nvq7iPAc88EKO35NFrpzj0hHZvC00wYC7pJIFbx\n6Qv5oVaANKgRoD1piOD0xYJnTeYeQJQ/EEY9nAo1vr4VugAuBURFQ6fINb1dGeqj9LteXSf2vuWP\nRvF784bGQzH5+YtJdMg5GH337GcbdxwW9ByVHcLnT5MLc7lPIfuqOINrzPsMmrVnc+437bx96uT7\ndxWaCXuZ7yL0p3y7X6V0Hbzv0Z36cSjh4gHY/+hkWNR8Adv0zkVAfyLfwiMIhA53TpS4O9RLlOgs\nYpwuuQwpfu/UywfukC6cCv+ocVbsYPA/W+/9udG8KRn/D8P5A/FYlzeycraBzeCy+dMHPopGh2sn\nWMpxyRhOVTvjpz9RGPobjKGEgZTR+Bwd+ojThmDTcdbwhDqZbHj4LPQTmSXqAXKnEUq7jWziBebO\n6a1vRTMxKE/1RnHjVUOsoLNOrkFKb8GpGkhxxUNdbSV6CUY2d+TIydTOTpCBySyAbwfvVN7y5k7J\nFoiNH1JL0x1uuPw1nvTb5a+O7m9X7VERfESDxgk41z7F9+29yjLATQsyW4gTX0THIvuW2Od/B3W0\n+aPZnZ0IOL+Doj8/x/HnEad/ih7/O25mztFPhK/4kJWLXPTnOL2TVZzzNClBOJS6wvErn+AVt3R8\nIjom0SRyJ48ohwNW7ogyXnz79NETf2qP/yztPqeoXHw4czr03yOfFDU=\n')]
 
 ### Load the compressed module sources ###
@@ -7,7 +8,7 @@ import sys, imp
 for name, source in module_sources:
     source = source.decode("base64").decode("zlib")
     mod = imp.new_module(name)
-    exec source in mod.__dict__
+    exec(source, mod.__dict__)
     sys.modules[name] = mod
 
 ### Original script follows ###
@@ -91,4 +92,4 @@ if __name__ == '__main__':
                        clean_dest=options.clean,
                        )
 
-    print "Got revision %s" % got_revision
+    print("Got revision %s" % got_revision)
diff --git a/testing/mozharness/external_tools/mouse_and_screen_resolution.py b/testing/mozharness/external_tools/mouse_and_screen_resolution.py
index 29e46e1bc0..63835e8bc4 100755
--- a/testing/mozharness/external_tools/mouse_and_screen_resolution.py
+++ b/testing/mozharness/external_tools/mouse_and_screen_resolution.py
@@ -9,6 +9,7 @@
 # Author(s):     Zambrano Gasparnian, Armen 
 # Target:        Python 2.5 or newer
 #
+from __future__ import print_function
 from optparse import OptionParser
 from ctypes import windll, Structure, c_ulong, byref
 try:
@@ -17,7 +18,7 @@ except:
     import simplejson as json
 import os
 import sys
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import socket
 import platform
 import time
@@ -28,15 +29,15 @@ default_mouse_position = {"x": 1010, "y": 10}
 def wfetch(url, retries=5):
     while True:
         try:
-            return urllib2.urlopen(url, timeout=30).read()
-        except urllib2.HTTPError, e:
-            print("Failed to fetch '%s': %s" % (url, str(e)))
-        except urllib2.URLError, e:
-            print("Failed to fetch '%s': %s" % (url, str(e)))
-        except socket.timeout, e:
-            print("Time out accessing %s: %s" % (url, str(e)))
-        except socket.error, e:
-            print("Socket error when accessing %s: %s" % (url, str(e)))
+            return six.moves.urllib.request.urlopen(url, timeout=30).read()
+        except six.moves.urllib.error.HTTPError as e:
+            print(("Failed to fetch '%s': %s" % (url, str(e))))
+        except six.moves.urllib.error.URLError as e:
+            print(("Failed to fetch '%s': %s" % (url, str(e))))
+        except socket.timeout as e:
+            print(("Time out accessing %s: %s" % (url, str(e))))
+        except socket.error as e:
+            print(("Socket error when accessing %s: %s" % (url, str(e))))
         if retries < 0:
             raise Exception("Could not fetch url '%s'" % url)
         retries -= 1
@@ -47,7 +48,7 @@ def main():
 
     if not (platform.version().startswith('6.1.760') and not 'PROGRAMFILES(X86)' in os.environ):
         # We only want to run this for Windows 7 32-bit
-        print "INFO: This script was written to be used with Windows 7 32-bit machines."
+        print("INFO: This script was written to be used with Windows 7 32-bit machines.")
         return 0
 
     parser = OptionParser()
@@ -61,7 +62,7 @@ def main():
 
     if (options.configuration_url == None and
         options.configuration_file == None):
-        print "You must specify --configuration-url or --configuration-file."
+        print("You must specify --configuration-url or --configuration-file.")
         return 1
 
     if options.configuration_file:
@@ -74,42 +75,42 @@ def main():
             conf_dict = json.loads(wfetch(options.configuration_url))
             new_screen_resolution = conf_dict["win7"]["screen_resolution"]
             new_mouse_position = conf_dict["win7"]["mouse_position"]
-        except urllib2.HTTPError, e:
-            print "This branch does not seem to have the configuration file %s" % str(e)
-            print "Let's fail over to 1024x768."
+        except six.moves.urllib.error.HTTPError as e:
+            print("This branch does not seem to have the configuration file %s" % str(e))
+            print("Let's fail over to 1024x768.")
             new_screen_resolution = default_screen_resolution
             new_mouse_position = default_mouse_position
-        except urllib2.URLError, e:
-            print "INFRA-ERROR: We couldn't reach hg.mozilla.org: %s" % str(e)
+        except six.moves.urllib.error.URLError as e:
+            print("INFRA-ERROR: We couldn't reach hg.mozilla.org: %s" % str(e))
             return 1
-        except Exception, e:
-            print "ERROR: We were not expecting any more exceptions: %s" % str(e)
+        except Exception as e:
+            print("ERROR: We were not expecting any more exceptions: %s" % str(e))
             return 1
 
     current_screen_resolution = queryScreenResolution()
-    print "Screen resolution (current): (%(x)s, %(y)s)" % (current_screen_resolution)
+    print("Screen resolution (current): (%(x)s, %(y)s)" % (current_screen_resolution))
 
     if current_screen_resolution == new_screen_resolution:
-        print "No need to change the screen resolution."
+        print("No need to change the screen resolution.")
     else:
-        print "Changing the screen resolution..."
+        print("Changing the screen resolution...")
         try:
             changeScreenResolution(new_screen_resolution["x"], new_screen_resolution["y"])
-        except Exception, e:
-            print "INFRA-ERROR: We have attempted to change the screen resolution but " + \
-                  "something went wrong: %s" % str(e)
+        except Exception as e:
+            print("INFRA-ERROR: We have attempted to change the screen resolution but " + \
+                  "something went wrong: %s" % str(e))
             return 1
         time.sleep(3)  # just in case
         current_screen_resolution = queryScreenResolution()
-        print "Screen resolution (new): (%(x)s, %(y)s)" % current_screen_resolution
+        print("Screen resolution (new): (%(x)s, %(y)s)" % current_screen_resolution)
 
-    print "Mouse position (current): (%(x)s, %(y)s)" % (queryMousePosition())
+    print("Mouse position (current): (%(x)s, %(y)s)" % (queryMousePosition()))
     setCursorPos(new_mouse_position["x"], new_mouse_position["y"])
     current_mouse_position = queryMousePosition()
-    print "Mouse position (new): (%(x)s, %(y)s)" % (current_mouse_position)
+    print("Mouse position (new): (%(x)s, %(y)s)" % (current_mouse_position))
 
     if current_screen_resolution != new_screen_resolution or current_mouse_position != new_mouse_position:
-        print "INFRA-ERROR: The new screen resolution or mouse positions are not what we expected"
+        print("INFRA-ERROR: The new screen resolution or mouse positions are not what we expected")
         return 1
     else:
         return 0
diff --git a/testing/mozharness/external_tools/robustcheckout.py b/testing/mozharness/external_tools/robustcheckout.py
index e801724c18..dc19ebcdb0 100644
--- a/testing/mozharness/external_tools/robustcheckout.py
+++ b/testing/mozharness/external_tools/robustcheckout.py
@@ -9,7 +9,6 @@ from a source repo using best practices to ensure optimal clone
 times and storage efficiency.
 """
 
-from __future__ import absolute_import
 
 import contextlib
 import errno
@@ -20,7 +19,7 @@ import re
 import socket
 import ssl
 import time
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 
 from mercurial.i18n import _
 from mercurial.node import hex
@@ -314,7 +313,7 @@ def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase,
             ui.warn('ssl error: %s\n' % e)
             handlenetworkfailure()
             return True
-        elif isinstance(e, urllib2.URLError):
+        elif isinstance(e, six.moves.urllib.error.URLError):
             if isinstance(e.reason, socket.error):
                 ui.warn('socket error: %s\n' % e.reason)
                 handlenetworkfailure()
@@ -342,7 +341,7 @@ def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase,
         try:
             res = hg.clone(ui, {}, cloneurl, dest=dest, update=False,
                            shareopts={'pool': sharebase, 'mode': 'identity'})
-        except (error.Abort, ssl.SSLError, urllib2.URLError) as e:
+        except (error.Abort, ssl.SSLError, six.moves.urllib.error.URLError) as e:
             if handlepullerror(e):
                 return callself()
             raise
@@ -401,7 +400,7 @@ def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase,
                 pullop = exchange.pull(repo, remote, heads=pullrevs)
                 if not pullop.rheads:
                     raise error.Abort('unable to pull requested revision')
-        except (error.Abort, ssl.SSLError, urllib2.URLError) as e:
+        except (error.Abort, ssl.SSLError, six.moves.urllib.error.URLError) as e:
             if handlepullerror(e):
                 return callself()
             raise
diff --git a/testing/mozharness/external_tools/virtualenv/setup.py b/testing/mozharness/external_tools/virtualenv/setup.py
index ee03bc5313..9d738d6b62 100644
--- a/testing/mozharness/external_tools/virtualenv/setup.py
+++ b/testing/mozharness/external_tools/virtualenv/setup.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import os
 import re
 import shutil
diff --git a/testing/mozharness/external_tools/virtualenv/site.py b/testing/mozharness/external_tools/virtualenv/site.py
index 4e426cdb66..5f7c992285 100644
--- a/testing/mozharness/external_tools/virtualenv/site.py
+++ b/testing/mozharness/external_tools/virtualenv/site.py
@@ -63,11 +63,12 @@ ImportError exception, it is silently ignored.
 
 """
 
+from __future__ import print_function
 import sys
 import os
 
 try:
-    import __builtin__ as builtins
+    import builtins as builtins
 except ImportError:
     import builtins
 try:
@@ -454,7 +455,7 @@ class _Printer(object):
         while 1:
             try:
                 for i in range(lineno, lineno + self.MAXLINES):
-                    print(self.__lines[i])
+                    print((self.__lines[i]))
             except IndexError:
                 break
             else:
@@ -462,9 +463,9 @@ class _Printer(object):
                 key = None
                 while key is None:
                     try:
-                        key = raw_input(prompt)
-                    except NameError:
                         key = input(prompt)
+                    except NameError:
+                        key = eval(input(prompt))
                     if key not in ('', 'q'):
                         key = None
                 if key == 'q':
@@ -723,16 +724,16 @@ def _script():
     if not args:
         print("sys.path = [")
         for dir in sys.path:
-            print("    %r," % (dir,))
+            print(("    %r," % (dir,)))
         print("]")
         def exists(path):
             if os.path.isdir(path):
                 return "exists"
             else:
                 return "doesn't exist"
-        print("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE)))
-        print("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE)))
-        print("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE)
+        print(("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE))))
+        print(("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE))))
+        print(("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE))
         sys.exit(0)
 
     buffer = []
@@ -742,7 +743,7 @@ def _script():
         buffer.append(USER_SITE)
 
     if buffer:
-        print(os.pathsep.join(buffer))
+        print((os.pathsep.join(buffer)))
         if ENABLE_USER_SITE:
             sys.exit(0)
         elif ENABLE_USER_SITE is False:
@@ -753,7 +754,7 @@ def _script():
             sys.exit(3)
     else:
         import textwrap
-        print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
+        print((textwrap.dedent(help % (sys.argv[0], os.pathsep))))
         sys.exit(10)
 
 if __name__ == '__main__':
diff --git a/testing/mozharness/external_tools/virtualenv/virtualenv.py b/testing/mozharness/external_tools/virtualenv/virtualenv.py
index e363021cc1..a46fccaf69 100755
--- a/testing/mozharness/external_tools/virtualenv/virtualenv.py
+++ b/testing/mozharness/external_tools/virtualenv/virtualenv.py
@@ -1,8 +1,10 @@
 #!/usr/bin/env python
 """Create a "virtual" Python installation"""
 
+from __future__ import print_function
 import os
 import sys
+import six
 
 # If we are running in a new interpreter to create a virtualenv,
 # we do NOT want paths from our existing location interfering with anything,
@@ -32,7 +34,7 @@ from distutils.util import strtobool
 from os.path import join
 
 try:
-    import ConfigParser
+    import six.moves.configparser
 except ImportError:
     import configparser as ConfigParser
 
@@ -40,14 +42,14 @@ __version__ = "15.0.1"
 virtualenv_version = __version__  # legacy
 
 if sys.version_info < (2, 6):
-    print('ERROR: %s' % sys.exc_info()[1])
+    print(('ERROR: %s' % sys.exc_info()[1]))
     print('ERROR: this script requires Python 2.6 or greater.')
     sys.exit(101)
 
 try:
-    basestring
+    str
 except NameError:
-    basestring = str
+    str = str
 
 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
 
@@ -82,7 +84,7 @@ else:
     try:
         import winreg
     except ImportError:
-        import _winreg as winreg
+        import six.moves.winreg as winreg
 
     def get_installed_pythons():
         try:
@@ -427,7 +429,7 @@ class ConfigOptionParser(optparse.OptionParser):
     configuration files and environmental variables
     """
     def __init__(self, *args, **kwargs):
-        self.config = ConfigParser.RawConfigParser()
+        self.config = six.moves.configparser.RawConfigParser()
         self.files = self.get_config_files()
         self.config.read(self.files)
         optparse.OptionParser.__init__(self, *args, **kwargs)
@@ -473,7 +475,7 @@ class ConfigOptionParser(optparse.OptionParser):
                     val = option.convert_value(key, val)
                 except optparse.OptionValueError:
                     e = sys.exc_info()[1]
-                    print("An error occurred during configuration: %s" % e)
+                    print(("An error occurred during configuration: %s" % e))
                     sys.exit(3)
                 defaults[option.dest] = val
         return defaults
@@ -506,7 +508,7 @@ class ConfigOptionParser(optparse.OptionParser):
         defaults = self.update_defaults(self.defaults.copy())  # ours
         for option in self._get_all_options():
             default = defaults.get(option.dest)
-            if isinstance(default, basestring):
+            if isinstance(default, str):
                 opt_str = option.get_opt_string()
                 defaults[option.dest] = option.check_value(opt_str, default)
         return optparse.Values(defaults)
@@ -673,8 +675,8 @@ def main():
         parser.print_help()
         sys.exit(2)
     if len(args) > 1:
-        print('There must be only one argument: DEST_DIR (you gave %s)' % (
-            ' '.join(args)))
+        print(('There must be only one argument: DEST_DIR (you gave %s)' % (
+            ' '.join(args))))
         parser.print_help()
         sys.exit(2)
 
@@ -840,8 +842,8 @@ def install_wheel(project_names, py_executable, search_dirs=None,
     # PIP_FIND_LINKS uses space as the path separator and thus cannot have paths
     # with spaces in them. Convert any of those to local file:// URL form.
     try:
-        from urlparse import urljoin
-        from urllib import pathname2url
+        from urllib.parse import urljoin
+        from urllib.request import pathname2url
     except ImportError:
         from urllib.parse import urljoin
         from urllib.request import pathname2url
@@ -968,12 +970,12 @@ def path_locations(home_dir):
             size = max(len(home_dir)+1, 256)
             buf = ctypes.create_unicode_buffer(size)
             try:
-                u = unicode
+                u = str
             except NameError:
                 u = str
             ret = GetShortPathName(u(home_dir), buf, size)
             if not ret:
-                print('Error: the path "%s" has a space in it' % home_dir)
+                print(('Error: the path "%s" has a space in it' % home_dir))
                 print('We could not determine the short pathname for it.')
                 print('Exiting.')
                 sys.exit(3)
@@ -1520,7 +1522,7 @@ def fix_lib64(lib_dir, symlink=True):
         return
     # Check we have a lib64 library path
     if not [p for p in distutils.sysconfig.get_config_vars().values()
-            if isinstance(p, basestring) and 'lib64' in p]:
+            if isinstance(p, str) and 'lib64' in p]:
         return
 
     logger.debug('This system uses lib64; symlinking lib64 to lib')
diff --git a/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/distutils-init.py b/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/distutils-init.py
index 29fc1da459..fe392b712b 100644
--- a/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/distutils-init.py
+++ b/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/distutils-init.py
@@ -25,9 +25,9 @@ else:
 from distutils import dist, sysconfig
 
 try:
-    basestring
+    str
 except NameError:
-    basestring = str
+    str = str
 
 ## patch build_ext (distutils doesn't know how to get the libs directory
 ## path on windows - it hardcodes the paths around the patched sys.prefix)
@@ -38,7 +38,7 @@ if sys.platform == 'win32':
         def finalize_options (self):
             if self.library_dirs is None:
                 self.library_dirs = []
-            elif isinstance(self.library_dirs, basestring):
+            elif isinstance(self.library_dirs, str):
                 self.library_dirs = self.library_dirs.split(os.pathsep)
             
             self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs"))
diff --git a/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/site.py b/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/site.py
index 7969769c36..2b14669adb 100644
--- a/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/site.py
+++ b/testing/mozharness/external_tools/virtualenv/virtualenv_embedded/site.py
@@ -63,10 +63,11 @@ ImportError exception, it is silently ignored.
 
 """
 
+from __future__ import print_function
 import sys
 import os
 try:
-    import __builtin__ as builtins
+    import builtins as builtins
 except ImportError:
     import builtins
 try:
@@ -453,7 +454,7 @@ class _Printer(object):
         while 1:
             try:
                 for i in range(lineno, lineno + self.MAXLINES):
-                    print(self.__lines[i])
+                    print((self.__lines[i]))
             except IndexError:
                 break
             else:
@@ -461,9 +462,9 @@ class _Printer(object):
                 key = None
                 while key is None:
                     try:
-                        key = raw_input(prompt)
-                    except NameError:
                         key = input(prompt)
+                    except NameError:
+                        key = eval(input(prompt))
                     if key not in ('', 'q'):
                         key = None
                 if key == 'q':
@@ -721,16 +722,16 @@ def _script():
     if not args:
         print("sys.path = [")
         for dir in sys.path:
-            print("    %r," % (dir,))
+            print(("    %r," % (dir,)))
         print("]")
         def exists(path):
             if os.path.isdir(path):
                 return "exists"
             else:
                 return "doesn't exist"
-        print("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE)))
-        print("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE)))
-        print("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE)
+        print(("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE))))
+        print(("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE))))
+        print(("ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE))
         sys.exit(0)
 
     buffer = []
@@ -740,7 +741,7 @@ def _script():
         buffer.append(USER_SITE)
 
     if buffer:
-        print(os.pathsep.join(buffer))
+        print((os.pathsep.join(buffer)))
         if ENABLE_USER_SITE:
             sys.exit(0)
         elif ENABLE_USER_SITE is False:
@@ -751,7 +752,7 @@ def _script():
             sys.exit(3)
     else:
         import textwrap
-        print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
+        print((textwrap.dedent(help % (sys.argv[0], os.pathsep))))
         sys.exit(10)
 
 if __name__ == '__main__':
diff --git a/testing/mozharness/mach_commands.py b/testing/mozharness/mach_commands.py
index f453397db7..87e9304bd7 100644
--- a/testing/mozharness/mach_commands.py
+++ b/testing/mozharness/mach_commands.py
@@ -9,8 +9,9 @@ import os
 import re
 import subprocess
 import sys
-import urllib
-import urlparse
+import urllib.request
+import urllib.parse
+import urllib.error
 
 import mozinfo
 
@@ -137,7 +138,7 @@ class MozharnessRunner(MozbuildObject):
 
 
     def path_to_url(self, path):
-        return urlparse.urljoin('file:', urllib.pathname2url(path))
+        return urllib.parse.urljoin('file:', urllib.request.pathname2url(path))
 
     def _installer_url(self):
         package_re = {
diff --git a/testing/mozharness/mozfile/__init__.py b/testing/mozharness/mozfile/__init__.py
index 37b8babb80..b276d461df 100644
--- a/testing/mozharness/mozfile/__init__.py
+++ b/testing/mozharness/mozfile/__init__.py
@@ -2,4 +2,4 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from mozfile import *
+from .mozfile import *
diff --git a/testing/mozharness/mozfile/mozfile.py b/testing/mozharness/mozfile/mozfile.py
index ac0edcab4f..132262a72f 100644
--- a/testing/mozharness/mozfile/mozfile.py
+++ b/testing/mozharness/mozfile/mozfile.py
@@ -4,14 +4,15 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 from contextlib import contextmanager
 import os
 import shutil
 import stat
 import tarfile
 import tempfile
-import urlparse
-import urllib2
+import six.moves.urllib.parse
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import zipfile
 import time
 
@@ -54,8 +55,8 @@ def extract_zip(src, dest):
     else:
         try:
             bundle = zipfile.ZipFile(src)
-        except Exception, e:
-            print "src: %s" % src
+        except Exception as e:
+            print("src: %s" % src)
             raise
 
     namelist = bundle.namelist()
@@ -161,7 +162,7 @@ def remove(path):
                     raise
                 retry_count += 1
 
-                print 'Retrying to remove "%s" because it is in use.' % path
+                print('Retrying to remove "%s" because it is in use.' % path)
                 time.sleep(retry_delay)
 
     if not os.path.exists(path):
@@ -347,7 +348,7 @@ def is_url(thing):
     Return True if thing looks like a URL.
     """
 
-    parsed = urlparse.urlparse(thing)
+    parsed = six.moves.urllib.parse.urlparse(thing)
     if 'scheme' in parsed:
         return len(parsed.scheme) >= 2
     else:
@@ -366,7 +367,7 @@ def load(resource):
 
     if not is_url(resource):
         # if no scheme is given, it is a file path
-        return file(resource)
+        return open(resource)
 
-    return urllib2.urlopen(resource)
+    return six.moves.urllib.request.urlopen(resource)
 
diff --git a/testing/mozharness/mozharness/base/config.py b/testing/mozharness/mozharness/base/config.py
index 9c17b33818..3af26cdba2 100644
--- a/testing/mozharness/mozharness/base/config.py
+++ b/testing/mozharness/mozharness/base/config.py
@@ -24,11 +24,12 @@ TODO:
   these settings are set.
 """
 
+from __future__ import print_function
 from copy import deepcopy
 from optparse import OptionParser, Option, OptionGroup
 import os
 import sys
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import socket
 import time
 try:
@@ -156,7 +157,7 @@ def parse_config_file(file_name, quiet=False, search_path=None,
     if file_name.endswith('.py'):
         global_dict = {}
         local_dict = {}
-        execfile(file_path, global_dict, local_dict)
+        exec(compile(open(file_path, "rb").read(), file_path, 'exec'), global_dict, local_dict)
         config = local_dict[config_dict_name]
     elif file_name.endswith('.json'):
         fh = open(file_path)
@@ -177,18 +178,18 @@ def download_config_file(url, file_name):
     max_sleeptime = 5 * 60
     while True:
         if n >= attempts:
-            print "Failed to download from url %s after %d attempts, quiting..." % (url, attempts)
+            print("Failed to download from url %s after %d attempts, quiting..." % (url, attempts))
             raise SystemError(-1)
         try:
-            contents = urllib2.urlopen(url, timeout=30).read()
+            contents = six.moves.urllib.request.urlopen(url, timeout=30).read()
             break
-        except urllib2.URLError, e:
-            print "Error downloading from url %s: %s" % (url, str(e))
-        except socket.timeout, e:
-            print "Time out accessing %s: %s" % (url, str(e))
-        except socket.error, e:
-            print "Socket error when accessing %s: %s" % (url, str(e))
-        print "Sleeping %d seconds before retrying" % sleeptime
+        except six.moves.urllib.error.URLError as e:
+            print("Error downloading from url %s: %s" % (url, str(e)))
+        except socket.timeout as e:
+            print("Time out accessing %s: %s" % (url, str(e)))
+        except socket.error as e:
+            print("Socket error when accessing %s: %s" % (url, str(e)))
+        print("Sleeping %d seconds before retrying" % sleeptime)
         time.sleep(sleeptime)
         sleeptime = sleeptime * 2
         if sleeptime > max_sleeptime:
@@ -199,8 +200,8 @@ def download_config_file(url, file_name):
         f = open(file_name, 'w')
         f.write(contents)
         f.close()
-    except IOError, e:
-        print "Error writing downloaded contents to file %s: %s" % (file_name, str(e))
+    except IOError as e:
+        print("Error writing downloaded contents to file %s: %s" % (file_name, str(e)))
         raise SystemError(-1)
 
 
@@ -390,8 +391,8 @@ class BaseConfig(object):
         for action in action_list:
             if action not in self.all_actions:
                 if not quiet:
-                    print("Invalid action %s not in %s!" % (action,
-                                                            self.all_actions))
+                    print(("Invalid action %s not in %s!" % (action,
+                                                            self.all_actions)))
                 raise SystemExit(-1)
         return action_list
 
@@ -401,17 +402,17 @@ class BaseConfig(object):
             sorted_indexes = sorted(indexes)
             for i in range(len(indexes)):
                 if indexes[i] != sorted_indexes[i]:
-                    print(("Action %s comes in different order in %s\n" +
-                           "than in %s") % (action_list[i], action_list, self.all_actions))
+                    print((("Action %s comes in different order in %s\n" +
+                           "than in %s") % (action_list[i], action_list, self.all_actions)))
                     raise SystemExit(-1)
         except ValueError as e:
-            print("Invalid action found: " + str(e))
+            print(("Invalid action found: " + str(e)))
             raise SystemExit(-1)
 
     def list_actions(self):
-        print "Actions available:"
+        print("Actions available:")
         for a in self.all_actions:
-            print "    " + ("*" if a in self.default_actions else " "), a
+            print("    " + ("*" if a in self.default_actions else " "), a)
         raise SystemExit(0)
 
     def get_cfgs_from_files(self, all_config_files, options):
@@ -446,9 +447,9 @@ class BaseConfig(object):
                     all_cfg_files_and_dicts.append((cf, parse_config_file(cf)))
             except Exception:
                 if cf in options.opt_config_files:
-                    print(
+                    print((
                         "WARNING: optional config file not found %s" % cf
-                    )
+                    ))
                 else:
                     raise
         return all_cfg_files_and_dicts
diff --git a/testing/mozharness/mozharness/base/diskutils.py b/testing/mozharness/mozharness/base/diskutils.py
index 745384ff92..726f90ecc6 100644
--- a/testing/mozharness/mozharness/base/diskutils.py
+++ b/testing/mozharness/mozharness/base/diskutils.py
@@ -116,7 +116,7 @@ class DiskSize(object):
         # depending on path format (unicode or not) and python version (2 or 3)
         # we need to call GetDiskFreeSpaceExW or GetDiskFreeSpaceExA
         called_function = ctypes.windll.kernel32.GetDiskFreeSpaceExA
-        if isinstance(path, unicode) or sys.version_info >= (3,):
+        if isinstance(path, str) or sys.version_info >= (3,):
             called_function = ctypes.windll.kernel32.GetDiskFreeSpaceExW
         # we're ready for the dll call. On error it returns 0
         if called_function(path,
diff --git a/testing/mozharness/mozharness/base/log.py b/testing/mozharness/mozharness/base/log.py
index 2c18b50c33..edaa27e5c1 100755
--- a/testing/mozharness/mozharness/base/log.py
+++ b/testing/mozharness/mozharness/base/log.py
@@ -24,6 +24,7 @@ TODO:
 - log rotation config
 """
 
+from __future__ import print_function
 from datetime import datetime
 import logging
 import os
@@ -91,9 +92,9 @@ class LogMixin(object):
         """
         if not hasattr(self, 'config') or self.config.get('log_to_console', True):
             if stderr:
-                print >> sys.stderr, message
+                print(message, file=sys.stderr)
             else:
-                print message
+                print(message)
 
     def log(self, message, level=INFO, exit_code=-1):
         """ log the message passed to it according to level, exit if level == FATAL
@@ -340,7 +341,7 @@ class OutputParser(LogMixin):
             output (str | list): string or list of string to parse
         """
 
-        if isinstance(output, basestring):
+        if isinstance(output, str):
             output = [output]
         for line in output:
             if not line or line.isspace():
diff --git a/testing/mozharness/mozharness/base/python.py b/testing/mozharness/mozharness/base/python.py
index cb5bfbc46c..b13df1fa74 100644
--- a/testing/mozharness/mozharness/base/python.py
+++ b/testing/mozharness/mozharness/base/python.py
@@ -14,7 +14,7 @@ import sys
 import json
 import socket
 import traceback
-import urlparse
+import six.moves.urllib.parse
 
 import mozharness
 from mozharness.base.script import (
@@ -26,6 +26,7 @@ from mozharness.base.script import (
 from mozharness.base.errors import VirtualenvErrorList
 from mozharness.base.log import WARNING, FATAL
 from mozharness.mozilla.proxxy import Proxxy
+import six
 
 external_tools_path = os.path.join(
     os.path.abspath(os.path.dirname(os.path.dirname(mozharness.__file__))),
@@ -162,7 +163,7 @@ class VirtualenvMixin(object):
                 self.log("package_versions: Program pip not in path", level=error_level)
                 return {}
             pip_freeze_output = self.get_output_from_command([pip, "freeze"], silent=True, ignore_errors=True)
-            if not isinstance(pip_freeze_output, basestring):
+            if not isinstance(pip_freeze_output, str):
                 self.fatal("package_versions: Error encountered running `pip freeze`: %s" % pip_freeze_output)
 
         for line in pip_freeze_output.splitlines():
@@ -190,7 +191,7 @@ class VirtualenvMixin(object):
         """
         Return whether the package is installed
         """
-        packages = self.package_versions(error_level=error_level).keys()
+        packages = list(self.package_versions(error_level=error_level).keys())
         return package_name.lower() in [package.lower() for package in packages]
 
     def install_module(self, module=None, module_url=None, install_method=None,
@@ -255,7 +256,7 @@ class VirtualenvMixin(object):
         proxxy = Proxxy(self.config, self.log_obj)
         trusted_hosts = set()
         for link in proxxy.get_proxies_and_urls(c.get('find_links', [])):
-            parsed = urlparse.urlparse(link)
+            parsed = six.moves.urllib.parse.urlparse(link)
 
             try:
                 socket.gethostbyname(parsed.hostname)
@@ -434,7 +435,7 @@ class VirtualenvMixin(object):
         """Import the virtualenv's packages into this Python interpreter."""
         bin_dir = os.path.dirname(self.query_python_path())
         activate = os.path.join(bin_dir, 'activate_this.py')
-        execfile(activate, dict(__file__=activate))
+        exec(compile(open(activate, "rb").read(), activate, 'exec'), dict(__file__=activate))
 
 
 # This is (sadly) a mixin for logging methods.
diff --git a/testing/mozharness/mozharness/base/script.py b/testing/mozharness/mozharness/base/script.py
index 828f4e39e8..e3b56524ac 100755
--- a/testing/mozharness/mozharness/base/script.py
+++ b/testing/mozharness/mozharness/base/script.py
@@ -11,6 +11,7 @@ script.py, along with config.py and log.py, represents the core of
 mozharness.
 """
 
+from __future__ import print_function
 import codecs
 from contextlib import contextmanager
 import datetime
@@ -31,11 +32,12 @@ import sys
 import tarfile
 import time
 import traceback
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import zipfile
-import httplib
-import urlparse
+import six.moves.http_client
+import six.moves.urllib.parse
 import hashlib
+import six
 if os.name == 'nt':
     try:
         import win32file
@@ -246,7 +248,7 @@ class ScriptMixin(PlatformMixin):
             str: in case `path` is a string. The result is the path with the new notation.
             type(path): `path` itself is returned in case `path` is not str type.
         """
-        if not isinstance(path, basestring):
+        if not isinstance(path, str):
             return path
         path = path.replace("\\", "/")
 
@@ -316,7 +318,7 @@ class ScriptMixin(PlatformMixin):
                  of the url.
         """
 
-        parsed = urlparse.urlsplit(url.rstrip('/'))
+        parsed = six.moves.urllib.parse.urlsplit(url.rstrip('/'))
         if parsed.path != '':
             return parsed.path.rsplit('/', 1)[-1]
         else:
@@ -342,8 +344,8 @@ class ScriptMixin(PlatformMixin):
         https://docs.python.org/2/library/urllib2.html#urllib2.urlopen
         """
         # http://bugs.python.org/issue13359 - urllib2 does not automatically quote the URL
-        url_quoted = urllib2.quote(url, safe='%/:=&?~#+!$,;\'@()*[]|')
-        return urllib2.urlopen(url_quoted, **kwargs)
+        url_quoted = six.moves.urllib.parse.quote(url, safe='%/:=&?~#+!$,;\'@()*[]|')
+        return six.moves.urllib.request.urlopen(url_quoted, **kwargs)
 
 
 
@@ -363,7 +365,7 @@ class ScriptMixin(PlatformMixin):
             BytesIO: contents of url
         '''
         self.info('Fetch {} into memory'.format(url))
-        parsed_url = urlparse.urlparse(url)
+        parsed_url = six.moves.urllib.parse.urlparse(url)
 
         if parsed_url.scheme in ('', 'file'):
             if not os.path.isfile(url):
@@ -374,9 +376,9 @@ class ScriptMixin(PlatformMixin):
             # In case we're referrencing a file without file://
             if parsed_url.scheme == '':
                 url = 'file://%s' % os.path.abspath(url)
-                parsed_url = urlparse.urlparse(url)
+                parsed_url = six.moves.urllib.parse.urlparse(url)
 
-        request = urllib2.Request(url)
+        request = six.moves.urllib.request.Request(url)
         # When calling fetch_url_into_memory() you should retry when we raise one of these exceptions:
         # * Bug 1300663 - HTTPError: HTTP Error 404: Not Found
         # * Bug 1300413 - HTTPError: HTTP Error 500: Internal Server Error
@@ -389,7 +391,7 @@ class ScriptMixin(PlatformMixin):
         # * Bug 1301807 - BadStatusLine: ''
         #
         # Bug 1309912 - Adding timeout in hopes to solve blocking on response.read() (bug 1300413)
-        response = urllib2.urlopen(request, timeout=30)
+        response = six.moves.urllib.request.urlopen(request, timeout=30)
 
         if parsed_url.scheme in ('http', 'https'):
             expected_file_size = int(response.headers.get('Content-Length'))
@@ -453,17 +455,17 @@ class ScriptMixin(PlatformMixin):
                 block = f.read(1024 ** 2)
                 if not block:
                     if f_length is not None and got_length != f_length:
-                        raise urllib2.URLError("Download incomplete; content-length was %d, but only received %d" % (f_length, got_length))
+                        raise six.moves.urllib.error.URLError("Download incomplete; content-length was %d, but only received %d" % (f_length, got_length))
                     break
                 local_file.write(block)
                 if f_length is not None:
                     got_length += len(block)
             local_file.close()
             return file_name
-        except urllib2.HTTPError, e:
+        except six.moves.urllib.error.HTTPError as e:
             self.warning("Server returned status %s %s for %s" % (str(e.code), str(e), url))
             raise
-        except urllib2.URLError, e:
+        except six.moves.urllib.error.URLError as e:
             self.warning("URL Error: %s" % url)
 
             # Failures due to missing local files won't benefit from retry.
@@ -471,7 +473,7 @@ class ScriptMixin(PlatformMixin):
             if isinstance(e.args[0], OSError) and e.args[0].errno == errno.ENOENT:
                 raise e.args[0]
 
-            remote_host = urlparse.urlsplit(url)[1]
+            remote_host = six.moves.urllib.parse.urlsplit(url)[1]
             if remote_host:
                 nslookup = self.query_exe('nslookup')
                 error_list = [{
@@ -482,10 +484,10 @@ class ScriptMixin(PlatformMixin):
                 self.run_command([nslookup, remote_host],
                                  error_list=error_list)
             raise
-        except socket.timeout, e:
+        except socket.timeout as e:
             self.warning("Timed out accessing %s: %s" % (url, str(e)))
             raise
-        except socket.error, e:
+        except socket.error as e:
             self.warning("Socket error when accessing %s: %s" % (url, str(e)))
             raise
 
@@ -511,8 +513,8 @@ class ScriptMixin(PlatformMixin):
         """
         retry_args = dict(
             failure_status=None,
-            retry_exceptions=(urllib2.HTTPError, urllib2.URLError,
-                              httplib.BadStatusLine,
+            retry_exceptions=(six.moves.urllib.error.HTTPError, six.moves.urllib.error.URLError,
+                              six.moves.http_client.BadStatusLine,
                               socket.timeout, socket.error),
             error_message="Can't download from %s to %s!" % (url, file_name),
             error_level=error_level,
@@ -537,7 +539,7 @@ class ScriptMixin(PlatformMixin):
     def _filter_entries(self, namelist, extract_dirs):
         """Filter entries of the archive based on the specified list of to extract dirs."""
         filter_partial = functools.partial(fnmatch.filter, namelist)
-        entries = itertools.chain(*map(filter_partial, extract_dirs or ['*']))
+        entries = itertools.chain(*list(map(filter_partial, extract_dirs or ['*'])))
 
         for entry in entries:
             yield entry
@@ -666,9 +668,9 @@ class ScriptMixin(PlatformMixin):
         # 1) Let's fetch the file
         retry_args = dict(
             retry_exceptions=(
-                urllib2.HTTPError,
-                urllib2.URLError,
-                httplib.BadStatusLine,
+                six.moves.urllib.error.HTTPError,
+                six.moves.urllib.error.URLError,
+                six.moves.http_client.BadStatusLine,
                 socket.timeout,
                 socket.error,
                 FetchedIncorrectFilesize,
@@ -768,11 +770,11 @@ class ScriptMixin(PlatformMixin):
         try:
             shutil.move(src, dest)
         # http://docs.python.org/tutorial/errors.html
-        except IOError, e:
+        except IOError as e:
             self.log("IO error: %s" % str(e),
                      level=error_level, exit_code=exit_code)
             return -1
-        except shutil.Error, e:
+        except shutil.Error as e:
             self.log("shutil error: %s" % str(e),
                      level=error_level, exit_code=exit_code)
             return -1
@@ -819,7 +821,7 @@ class ScriptMixin(PlatformMixin):
                 outfile.writelines(infile)
                 outfile.close()
                 infile.close()
-            except IOError, e:
+            except IOError as e:
                 self.log("Can't compress %s to %s: %s!" % (src, dest, str(e)),
                          level=error_level)
                 return -1
@@ -827,7 +829,7 @@ class ScriptMixin(PlatformMixin):
             self.log("Copying %s to %s" % (src, dest), level=log_level)
             try:
                 shutil.copyfile(src, dest)
-            except (IOError, shutil.Error), e:
+            except (IOError, shutil.Error) as e:
                 self.log("Can't copy %s to %s: %s!" % (src, dest, str(e)),
                          level=error_level)
                 return -1
@@ -835,7 +837,7 @@ class ScriptMixin(PlatformMixin):
         if copystat:
             try:
                 shutil.copystat(src, dest)
-            except (IOError, shutil.Error), e:
+            except (IOError, shutil.Error) as e:
                 self.log("Can't copy attributes of %s to %s: %s!" % (src, dest, str(e)),
                          level=error_level)
                 return -1
@@ -968,7 +970,7 @@ class ScriptMixin(PlatformMixin):
         self.info("Reading from file %s" % file_path)
         try:
             fh = open(file_path, open_mode)
-        except IOError, err:
+        except IOError as err:
             self.log("unable to open %s: %s" % (file_path, err.strerror),
                      level=error_level)
             yield None, err
@@ -1111,7 +1113,7 @@ class ScriptMixin(PlatformMixin):
                 status = action(*args, **kwargs)
                 if good_statuses and status not in good_statuses:
                     retry = True
-            except retry_exceptions, e:
+            except retry_exceptions as e:
                 retry = True
                 error_message = "%s\nCaught exception: %s" % (error_message, str(e))
                 self.log('retry: attempt #%d caught exception: %s' % (n, str(e)), level=INFO)
@@ -1232,7 +1234,7 @@ class ScriptMixin(PlatformMixin):
         if isinstance(exe, dict):
             found = False
             # allow for searchable paths of the buildbot exe
-            for name, path in exe.iteritems():
+            for name, path in exe.items():
                 if isinstance(path, list) or isinstance(path, tuple):
                     path = [x % repl_dict for x in path]
                     if all([os.path.exists(section) for section in path]):
@@ -1390,7 +1392,7 @@ class ScriptMixin(PlatformMixin):
                             break
                         parser.add_lines(line)
                 returncode = p.returncode
-        except OSError, e:
+        except OSError as e:
             level = error_level
             if halt_on_failure:
                 level = FATAL
@@ -2149,7 +2151,7 @@ class BaseScript(ScriptMixin, LogMixin, object):
                 except ValueError:
                     """log is closed; print as a default. Ran into this
                     when calling from __del__()"""
-                    print "### Log is closed! (%s)" % item['message']
+                    print("### Log is closed! (%s)" % item['message'])
 
     def add_summary(self, message, level=INFO):
         self.summary_list.append({'message': message, 'level': level})
diff --git a/testing/mozharness/mozharness/base/transfer.py b/testing/mozharness/mozharness/base/transfer.py
index 014c665a14..a298abfdab 100755
--- a/testing/mozharness/mozharness/base/transfer.py
+++ b/testing/mozharness/mozharness/base/transfer.py
@@ -9,7 +9,7 @@
 
 import os
 import pprint
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 try:
     import simplejson as json
     assert json
@@ -114,7 +114,7 @@ class TransferMixin(object):
         self.log("Attempting to download %s; timeout=%i" % (url, timeout),
                  level=log_level)
         try:
-            r = urllib2.urlopen(url, timeout=timeout)
+            r = six.moves.urllib.request.urlopen(url, timeout=timeout)
             j = json.load(r)
             self.log(pprint.pformat(j), level=log_level)
         except:
diff --git a/testing/mozharness/mozharness/base/vcs/gittool.py b/testing/mozharness/mozharness/base/vcs/gittool.py
index d6c609ea02..b835bacb94 100644
--- a/testing/mozharness/mozharness/base/vcs/gittool.py
+++ b/testing/mozharness/mozharness/base/vcs/gittool.py
@@ -1,6 +1,6 @@
 import os
 import re
-import urlparse
+import six.moves.urllib.parse
 
 from mozharness.base.script import ScriptMixin
 from mozharness.base.log import LogMixin, OutputParser
@@ -80,8 +80,8 @@ class GittoolVCS(ScriptMixin, LogMixin):
             cmd.append('--clean')
 
         for base_mirror_url in self.config.get('gittool_base_mirror_urls', self.config.get('vcs_base_mirror_urls', [])):
-            bits = urlparse.urlparse(repo)
-            mirror_url = urlparse.urljoin(base_mirror_url, bits.path)
+            bits = six.moves.urllib.parse.urlparse(repo)
+            mirror_url = six.moves.urllib.parse.urljoin(base_mirror_url, bits.path)
             cmd.extend(['--mirror', mirror_url])
 
         cmd.extend([repo, dest])
diff --git a/testing/mozharness/mozharness/base/vcs/mercurial.py b/testing/mozharness/mozharness/base/vcs/mercurial.py
index 71e5e3ea03..e89b1643b8 100755
--- a/testing/mozharness/mozharness/base/vcs/mercurial.py
+++ b/testing/mozharness/mozharness/base/vcs/mercurial.py
@@ -11,7 +11,7 @@ import os
 import re
 import subprocess
 from collections import namedtuple
-from urlparse import urlsplit
+from urllib.parse import urlsplit
 import hashlib
 
 import sys
@@ -299,7 +299,7 @@ class MercurialVCS(ScriptMixin, LogMixin, TransferMixin):
                         branch = "default"
                     revs.append((rev, branch))
                 return revs
-            except subprocess.CalledProcessError, inst:
+            except subprocess.CalledProcessError as inst:
                 # In some situations, some versions of Mercurial return "1"
                 # if no changes are found, so we need to ignore this return
                 # code
@@ -419,7 +419,7 @@ class MercurialVCS(ScriptMixin, LogMixin, TransferMixin):
                           ssh_username=ssh_username,
                           ssh_key=ssh_key)
                 return
-            except VCSException, e:
+            except VCSException as e:
                 self.debug("Hit error when trying to push: %s" % str(e))
                 if n == max_attempts:
                     self.debug("Tried %d times, giving up" % max_attempts)
@@ -435,7 +435,7 @@ class MercurialVCS(ScriptMixin, LogMixin, TransferMixin):
                     self.run_command(self.hg + ['rebase'], cwd=localrepo,
                                      error_list=HgErrorList,
                                      throw_exception=True)
-                except subprocess.CalledProcessError, e:
+                except subprocess.CalledProcessError as e:
                     self.debug("Failed to rebase: %s" % str(e))
                     # clean up any hanging rebase. ignore errors if we aren't
                     # in the middle of a rebase.
@@ -481,7 +481,7 @@ class MercurialVCS(ScriptMixin, LogMixin, TransferMixin):
             #
             # So we grab the first element ("28537" in this case) and then pull
             # out the 'date' field.
-            pushid = contents.iterkeys().next()
+            pushid = next(contents.keys())
             self.info('Pushid is: %s' % pushid)
             pushdate = contents[pushid]['date']
             self.info('Pushdate is: %s' % pushdate)
diff --git a/testing/mozharness/mozharness/lib/python/authentication.py b/testing/mozharness/mozharness/lib/python/authentication.py
index 2e5f83f373..6944d2321b 100644
--- a/testing/mozharness/mozharness/lib/python/authentication.py
+++ b/testing/mozharness/mozharness/lib/python/authentication.py
@@ -5,6 +5,7 @@
 # ***** END LICENSE BLOCK *****
 
 """module for http authentication operations"""
+from __future__ import print_function
 import getpass
 import os
 
@@ -33,15 +34,15 @@ def get_credentials():
             os.remove(CREDENTIALS_PATH)
     else:
         https_username = \
-                raw_input("Please enter your full LDAP email address: ")
+                input("Please enter your full LDAP email address: ")
 
         with open(CREDENTIALS_PATH, "w+") as file_handler:
             file_handler.write("%s\n" % https_username)
 
-        os.chmod(CREDENTIALS_PATH, 0600)
+        os.chmod(CREDENTIALS_PATH, 0o600)
 
     if not LDAP_PASSWORD:
-        print "Please enter your LDAP password (we won't store it):"
+        print("Please enter your LDAP password (we won't store it):")
         LDAP_PASSWORD = getpass.getpass()
 
     return https_username, LDAP_PASSWORD
diff --git a/testing/mozharness/mozharness/mozilla/bouncer/submitter.py b/testing/mozharness/mozharness/mozilla/bouncer/submitter.py
index 43983dca8d..7c92671eb1 100644
--- a/testing/mozharness/mozharness/mozilla/bouncer/submitter.py
+++ b/testing/mozharness/mozharness/mozilla/bouncer/submitter.py
@@ -1,10 +1,10 @@
 import base64
-import httplib
+import six.moves.http_client
 import socket
 import sys
 import traceback
-import urllib
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 from xml.dom.minidom import parseString
 
 from mozharness.base.log import FATAL
@@ -16,7 +16,7 @@ class BouncerSubmitterMixin(object):
             return self.credentials
         global_dict = {}
         local_dict = {}
-        execfile(self.config["credentials_file"], global_dict, local_dict)
+        exec(compile(open(self.config["credentials_file"], "rb").read(), self.config["credentials_file"], 'exec'), global_dict, local_dict)
         self.credentials = (local_dict["tuxedoUsername"],
                             local_dict["tuxedoPassword"])
         return self.credentials
@@ -24,8 +24,8 @@ class BouncerSubmitterMixin(object):
     def api_call(self, route, data, error_level=FATAL, retry_config=None):
         retry_args = dict(
             failure_status=None,
-            retry_exceptions=(urllib2.HTTPError, urllib2.URLError,
-                              httplib.BadStatusLine,
+            retry_exceptions=(six.moves.urllib.error.HTTPError, six.moves.urllib.error.URLError,
+                              six.moves.http_client.BadStatusLine,
                               socket.timeout, socket.error),
             error_message="call to %s failed" % (route),
             error_level=error_level,
@@ -43,9 +43,9 @@ class BouncerSubmitterMixin(object):
     def _api_call(self, route, data):
         api_prefix = self.config["bouncer-api-prefix"]
         api_url = "%s/%s" % (api_prefix, route)
-        request = urllib2.Request(api_url)
+        request = six.moves.urllib.request.Request(api_url)
         if data:
-            post_data = urllib.urlencode(data, doseq=True)
+            post_data = six.moves.urllib.parse.urlencode(data, doseq=True)
             request.add_data(post_data)
             self.info("POST data: %s" % post_data)
         credentials = self.query_credentials()
@@ -54,17 +54,17 @@ class BouncerSubmitterMixin(object):
             request.add_header("Authorization", "Basic %s" % auth.strip())
         try:
             self.info("Submitting to %s" % api_url)
-            res = urllib2.urlopen(request, timeout=60).read()
+            res = six.moves.urllib.request.urlopen(request, timeout=60).read()
             self.info("Server response")
             self.info(res)
             return res
-        except urllib2.HTTPError as e:
+        except six.moves.urllib.error.HTTPError as e:
             self.warning("Cannot access %s" % api_url)
             traceback.print_exc(file=sys.stdout)
             self.warning("Returned page source:")
             self.warning(e.read())
             raise
-        except urllib2.URLError:
+        except six.moves.urllib.error.URLError:
             traceback.print_exc(file=sys.stdout)
             self.warning("Cannot access %s" % api_url)
             raise
@@ -74,14 +74,14 @@ class BouncerSubmitterMixin(object):
         except socket.error as e:
             self.warning("Socket error when accessing %s: %s" % (api_url, e))
             raise
-        except httplib.BadStatusLine as e:
+        except six.moves.http_client.BadStatusLine as e:
             self.warning('BadStatusLine accessing %s: %s' % (api_url, e))
             raise
 
     def product_exists(self, product_name):
         self.info("Checking if %s already exists" % product_name)
         res = self.api_call("product_show?product=%s" %
-                            urllib.quote(product_name), data=None)
+                            six.moves.urllib.parse.quote(product_name), data=None)
         try:
             xml = parseString(res)
             # API returns  if the product doesn't exist
diff --git a/testing/mozharness/mozharness/mozilla/buildbot.py b/testing/mozharness/mozharness/mozilla/buildbot.py
index e17343633b..78e34bf558 100755
--- a/testing/mozharness/mozharness/mozilla/buildbot.py
+++ b/testing/mozharness/mozharness/mozilla/buildbot.py
@@ -133,7 +133,7 @@ class BuildbotMixin(object):
         if not os.path.isdir(dir_name):
             self.mkdir_p(dir_name)
         if not prop_list:
-            prop_list = self.buildbot_properties.keys()
+            prop_list = list(self.buildbot_properties.keys())
             self.info("Writing buildbot properties to %s" % file_name)
         else:
             if not isinstance(prop_list, (list, tuple)):
@@ -171,7 +171,7 @@ class BuildbotMixin(object):
             if self.buildbot_config['sourcestamp']['changes'][0].get('comments'):
                 sendchange += ['--comments', self.buildbot_config['sourcestamp']['changes'][0]['comments'].encode('ascii', 'ignore')]
         if sendchange_props:
-            for key, value in sendchange_props.iteritems():
+            for key, value in sendchange_props.items():
                 sendchange.extend(['--property', '%s:%s' % (key, value)])
         else:
             if self.buildbot_config["properties"].get("builduid"):
diff --git a/testing/mozharness/mozharness/mozilla/building/buildbase.py b/testing/mozharness/mozharness/mozilla/building/buildbase.py
index 9fd507816d..b20e74298a 100755
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -55,7 +55,7 @@ from mozharness.base.python import (
     VirtualenvMixin,
 )
 
-AUTOMATION_EXIT_CODES = EXIT_STATUS_DICT.values()
+AUTOMATION_EXIT_CODES = list(EXIT_STATUS_DICT.values())
 AUTOMATION_EXIT_CODES.sort()
 
 MISSING_CFG_KEY_MSG = "The key '%s' could not be determined \
@@ -466,7 +466,7 @@ class BuildOptionParser(object):
                      "shortname: %s \n\t-- a valid path in %s \n\t-- a "
                      "valid variant for the given platform and bits." % (
                          prospective_cfg_path,
-                         str(cls.build_variants.keys()),
+                         str(list(cls.build_variants.keys())),
                          str(cls.config_file_search_path)))
         parser.values.config_files.append(valid_variant_cfg_path)
         setattr(parser.values, option.dest, value)  # the pool
@@ -528,7 +528,7 @@ BUILD_BASE_CONFIG_OPTIONS = [
         "help": "Sets the build type and will determine appropriate"
                 " additional config to use. Either pass a config path"
                 " or use a valid shortname from: "
-                "%s" % (BuildOptionParser.build_variants.keys(),)}],
+                "%s" % (list(BuildOptionParser.build_variants.keys()),)}],
     [['--build-pool'], {
         "action": "callback",
         "callback": BuildOptionParser.set_build_pool,
@@ -676,7 +676,7 @@ platform '%(platform)s'. Updating self.config with the following from \
                     }
                 )
         if c.get("platform_overrides"):
-            if c['stage_platform'] in c['platform_overrides'].keys():
+            if c['stage_platform'] in list(c['platform_overrides'].keys()):
                 self.info(
                     pf_override_msg % {
                         'branch': c['branch'],
@@ -960,7 +960,7 @@ or run without that action (ie: --no-{action})"
         dirs = self.query_abs_dirs()
         check_test_env = {}
         if c.get('check_test_env'):
-            for env_var, env_value in c['check_test_env'].iteritems():
+            for env_var, env_value in c['check_test_env'].items():
                 check_test_env[env_var] = env_value % dirs
         return check_test_env
 
@@ -1224,8 +1224,8 @@ or run without that action (ie: --no-{action})"
         # persisted to file rather than use whats in the buildbot_properties
         # live object so we become less action dependant.
         all_current_props = dict(
-            chain(self.buildbot_config['properties'].items(),
-                  self.buildbot_properties.items())
+            chain(list(self.buildbot_config['properties'].items()),
+                  list(self.buildbot_properties.items()))
         )
         # graph_server_post.py expects a file with 'properties' key
         graph_props = dict(properties=all_current_props)
@@ -1250,7 +1250,7 @@ or run without that action (ie: --no-{action})"
                 if console_output:
                     self.info("Properties set from 'mach build'")
                     self.info(pprint.pformat(build_props))
-            for key, prop in build_props.iteritems():
+            for key, prop in build_props.items():
                 if prop != 'UNKNOWN':
                     self.set_buildbot_property(key, prop, write_to_file=True)
         else:
@@ -1341,7 +1341,7 @@ or run without that action (ie: --no-{action})"
         dirs = self.query_abs_dirs()
         auth = os.path.join(os.getcwd(), self.config['taskcluster_credentials_file'])
         credentials = {}
-        execfile(auth, credentials)
+        exec(compile(open(auth, "rb").read(), auth, 'exec'), credentials)
         self.client_id = credentials.get('taskcluster_clientId')
         self.access_token = credentials.get('taskcluster_accessToken')
 
@@ -2147,7 +2147,7 @@ or run without that action (ie: --no-{action})"
                            "Valid return codes %s" % (self.return_code,
                                                       AUTOMATION_EXIT_CODES))
                 self.return_code = 2
-            for status, return_code in EXIT_STATUS_DICT.iteritems():
+            for status, return_code in EXIT_STATUS_DICT.items():
                 if return_code == self.return_code:
                     self.buildbot_status(status, TBPL_STATUS_DICT[status])
         self.summary()
diff --git a/testing/mozharness/mozharness/mozilla/building/hazards.py b/testing/mozharness/mozharness/mozilla/building/hazards.py
index 6de235f892..3653c165ba 100644
--- a/testing/mozharness/mozharness/mozilla/building/hazards.py
+++ b/testing/mozharness/mozharness/mozilla/building/hazards.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import os
 import json
 import re
@@ -104,7 +105,7 @@ jobs = 4
 """ % values
 
         defaults_path = os.path.join(analysis_dir, 'defaults.py')
-        file(defaults_path, "w").write(defaults)
+        open(defaults_path, "w").write(defaults)
         builder.log("Wrote analysis config file " + defaults_path)
 
         build_script = builder.config['build_command']
@@ -165,14 +166,14 @@ jobs = 4
                  ('hazards.txt',
                   'hazards',
                   'list of just the hazards, together with gcFunction reason for each'))
-        for f, short, long in files:
+        for f, short, int in files:
             builder.copy_to_upload_dir(os.path.join(analysis_dir, f),
                                        short_desc=short,
-                                       long_desc=long,
+                                       long_desc=int,
                                        compress=False,  # blobber will compress
                                        upload_dir=upload_dir)
         print("== Hazards (temporarily inline here, beware weirdly interleaved output, see bug 1211402) ==")
-        print(file(os.path.join(analysis_dir, "hazards.txt")).read())
+        print((open(os.path.join(analysis_dir, "hazards.txt")).read()))
 
     def upload_results(self, builder):
         """Upload the results of the analysis."""
diff --git a/testing/mozharness/mozharness/mozilla/l10n/locales.py b/testing/mozharness/mozharness/mozilla/l10n/locales.py
index 24920ae445..f6fad57aa3 100755
--- a/testing/mozharness/mozharness/mozilla/l10n/locales.py
+++ b/testing/mozharness/mozharness/mozilla/l10n/locales.py
@@ -8,7 +8,7 @@
 """
 
 import os
-from urlparse import urljoin
+from urllib.parse import urljoin
 import sys
 from copy import deepcopy
 
diff --git a/testing/mozharness/mozharness/mozilla/mapper.py b/testing/mozharness/mozharness/mozilla/mapper.py
index c5a2d48959..3cc3e00797 100644
--- a/testing/mozharness/mozharness/mozilla/mapper.py
+++ b/testing/mozharness/mozharness/mozilla/mapper.py
@@ -6,7 +6,7 @@
 # ***** END LICENSE BLOCK *****
 """Support for hg/git mapper
 """
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import time
 try:
     import simplejson as json
@@ -47,7 +47,7 @@ class MapperMixin:
         n = 1
         while n <= attempts:
             try:
-                r = urllib2.urlopen(url, timeout=10)
+                r = six.moves.urllib.request.urlopen(url, timeout=10)
                 j = json.loads(r.readline())
                 if j['%s_rev' % vcs] is None:
                     if require_answer:
@@ -55,7 +55,7 @@ class MapperMixin:
                     else:
                         self.warning("Mapper returned a revision of None.  Accepting because require_answer is False.")
                 return j['%s_rev' % vcs]
-            except Exception, err:
+            except Exception as err:
                 self.warning('Error: %s' % str(err))
                 if n == attempts:
                     self.fatal('Giving up on %s %s revision for %s.' % (project_name, vcs, rev))
diff --git a/testing/mozharness/mozharness/mozilla/mar.py b/testing/mozharness/mozharness/mozilla/mar.py
index dbe3b96a0d..f8cc860788 100644
--- a/testing/mozharness/mozharness/mozilla/mar.py
+++ b/testing/mozharness/mozharness/mozilla/mar.py
@@ -8,7 +8,7 @@
 
 import os
 import sys
-import ConfigParser
+import six.moves.configparser
 
 # load modules from parent dir
 sys.path.insert(1, os.path.dirname(sys.path[0]))
@@ -21,7 +21,7 @@ CONFIG = {
 
 
 def query_ini_file(ini_file, section, option):
-    ini = ConfigParser.SafeConfigParser()
+    ini = six.moves.configparser.SafeConfigParser()
     ini.read(ini_file)
     return ini.get(section, option)
 
@@ -67,7 +67,7 @@ class MarMixin(object):
                 self.info("downloaded %s" % full_path)
             else:
                 self.info("found %s, skipping download" % full_path)
-            self.chmod(full_path, 0755)
+            self.chmod(full_path, 0o755)
 
     def _temp_mar_base_dir(self):
         """a base dir for unpacking mars"""
diff --git a/testing/mozharness/mozharness/mozilla/mock.py b/testing/mozharness/mozharness/mozilla/mock.py
index f8587c0d66..b9684fef8f 100644
--- a/testing/mozharness/mozharness/mozilla/mock.py
+++ b/testing/mozharness/mozharness/mozilla/mock.py
@@ -101,7 +101,7 @@ class MockMixin(object):
             cmd += ['--unpriv']
         cmd += ['--shell']
 
-        if not isinstance(command, basestring):
+        if not isinstance(command, str):
             command = subprocess.list2cmdline(command)
 
         # XXX - Hack - gets around AB_CD=%(locale)s type arguments
diff --git a/testing/mozharness/mozharness/mozilla/proxxy.py b/testing/mozharness/mozharness/mozilla/proxxy.py
index b9f14d5f2c..d0028a3f43 100644
--- a/testing/mozharness/mozharness/mozilla/proxxy.py
+++ b/testing/mozharness/mozharness/mozilla/proxxy.py
@@ -2,7 +2,7 @@
    proxxy instances (if available). The goal of Proxxy is to lower the traffic
    from the cloud to internal servers.
 """
-import urlparse
+import six.moves.urllib.parse
 import socket
 from mozharness.base.log import INFO, ERROR, LogMixin
 from mozharness.base.script import ScriptMixin
@@ -67,7 +67,7 @@ class Proxxy(ScriptMixin, LogMixin):
         proxxy_urls = config.get('urls', [])
         proxxy_instances = config.get('instances', [])
 
-        url_parts = urlparse.urlsplit(url)
+        url_parts = six.moves.urllib.parse.urlsplit(url)
         url_path = url_parts.path
         if url_parts.query:
             url_path += "?" + url_parts.query
diff --git a/testing/mozharness/mozharness/mozilla/release.py b/testing/mozharness/mozharness/mozilla/release.py
index 52a84cdba3..966db77a62 100755
--- a/testing/mozharness/mozharness/mozilla/release.py
+++ b/testing/mozharness/mozharness/mozilla/release.py
@@ -9,7 +9,27 @@
 """
 
 import os
-from distutils.version import LooseVersion, StrictVersion
+import re
+class LooseVersion:
+    """Simple version comparison (replacement for distutils.version.LooseVersion)."""
+    def __init__(self, vstring):
+        self.vstring = vstring
+        self.version = [int(x) if x.isdigit() else x for x in re.split(r'[.\-]', vstring)]
+    def __str__(self): return self.vstring
+    def __repr__(self): return "LooseVersion('%s')" % self.vstring
+    def _cmp(self, other):
+        if not isinstance(other, LooseVersion):
+            other = LooseVersion(str(other))
+        try:
+            if self.version == other.version: return 0
+            if self.version < other.version: return -1
+            return 1
+        except TypeError: return -1
+    def __lt__(self, o): return self._cmp(o) < 0
+    def __le__(self, o): return self._cmp(o) <= 0
+    def __eq__(self, o): return self._cmp(o) == 0
+    def __ge__(self, o): return self._cmp(o) >= 0
+    def __gt__(self, o): return self._cmp(o) > 0, StrictVersion
 
 from mozharness.base.config import parse_config_file
 
diff --git a/testing/mozharness/mozharness/mozilla/repo_manupulation.py b/testing/mozharness/mozharness/mozilla/repo_manupulation.py
index a2dfc46a2f..80c68ed182 100644
--- a/testing/mozharness/mozharness/mozilla/repo_manupulation.py
+++ b/testing/mozharness/mozharness/mozilla/repo_manupulation.py
@@ -114,7 +114,7 @@ class MercurialRepoManipulationMixin(object):
 
     def hg_tag(self, cwd, tags, user=None, message=None, revision=None,
                force=None, halt_on_failure=True):
-        if isinstance(tags, basestring):
+        if isinstance(tags, str):
             tags = [tags]
         cmd = self.query_exe('hg', return_type='list') + ['tag']
         if not message:
diff --git a/testing/mozharness/mozharness/mozilla/secrets.py b/testing/mozharness/mozharness/mozilla/secrets.py
index d40964bd67..164679e5fb 100644
--- a/testing/mozharness/mozharness/mozilla/secrets.py
+++ b/testing/mozharness/mozharness/mozilla/secrets.py
@@ -9,7 +9,7 @@
 
 import os
 import mozharness
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import json
 from mozharness.base.log import ERROR
 
@@ -22,7 +22,7 @@ class SecretsMixin(object):
         # within a taskcluster task.  Outside of that environment, do not
         # use this action.
         url = "http://taskcluster/secrets/v1/secret/" + secret_name
-        res = urllib2.urlopen(url)
+        res = six.moves.urllib.request.urlopen(url)
         if res.getcode() != 200:
             self.fatal("Error fetching from secrets API:" + res.read())
 
diff --git a/testing/mozharness/mozharness/mozilla/structuredlog.py b/testing/mozharness/mozharness/mozilla/structuredlog.py
index d87c5ebdc3..0d65ac8e79 100644
--- a/testing/mozharness/mozharness/mozilla/structuredlog.py
+++ b/testing/mozharness/mozharness/mozilla/structuredlog.py
@@ -111,7 +111,7 @@ class StructuredOutputParser(OutputParser):
             'suite_end': 'No suite end message was emitted by this harness.',
             'test_end': 'No checks run.',
         }
-        for action, diagnostic_message in required_actions.iteritems():
+        for action, diagnostic_message in required_actions.items():
             if action not in summary.action_counts:
                 self.log(diagnostic_message, ERROR)
                 self.update_levels(*error_pair)
diff --git a/testing/mozharness/mozharness/mozilla/taskcluster_helper.py b/testing/mozharness/mozharness/mozilla/taskcluster_helper.py
index 6921b8938d..c2b383fa15 100644
--- a/testing/mozharness/mozharness/mozilla/taskcluster_helper.py
+++ b/testing/mozharness/mozharness/mozilla/taskcluster_helper.py
@@ -3,7 +3,7 @@
 """
 import os
 from datetime import datetime, timedelta
-from urlparse import urljoin
+from urllib.parse import urljoin
 
 from mozharness.base.log import LogMixin
 
diff --git a/testing/mozharness/mozharness/mozilla/testing/device.py b/testing/mozharness/mozharness/mozilla/testing/device.py
index fea43ba20e..fe0b0a1dc4 100644
--- a/testing/mozharness/mozharness/mozilla/testing/device.py
+++ b/testing/mozharness/mozharness/mozilla/testing/device.py
@@ -438,7 +438,7 @@ class SUTDeviceHandler(BaseDeviceHandler):
             self.devicemanager = DeviceManagerSUT(c['device_ip'])
             # TODO configurable?
             self.devicemanager.debug = c.get('devicemanager_debug_level', 0)
-        except ImportError, e:
+        except ImportError as e:
             self.fatal("Can't import DeviceManagerSUT! %s\nDid you check out talos?" % str(e))
         return self.devicemanager
 
@@ -524,7 +524,7 @@ class SUTDeviceHandler(BaseDeviceHandler):
         try:
             dm.sendCMD(['settime %s' % s])
             return True
-        except self.DMError, e:
+        except self.DMError as e:
             self.add_device_flag(DEVICE_CANT_SET_TIME)
             self.fatal("Exception while setting device time: %s" % str(e))
 
@@ -564,7 +564,7 @@ class SUTDeviceHandler(BaseDeviceHandler):
                 self.info(repr(dm.getInfo('memory')))
                 self.info(repr(dm.getInfo('uptime')))
                 self.info(repr(dm.sendCMD(['exec su -c "logcat -d -v time *:W"'])))
-            except Exception, e:
+            except Exception as e:
                 self.info("Exception hit while trying to run logcat: %s" % str(e))
                 self.fatal("Remote Device Error: can't run logcat")
         except self.DMError:
@@ -676,7 +676,7 @@ device_config_options = [[
     {"action": "store",
      "type": "choice",
      "dest": "device_protocol",
-     "choices": DEVICE_PROTOCOL_DICT.keys(),
+     "choices": list(DEVICE_PROTOCOL_DICT.keys()),
      "help": "Specify the device communication protocol."
      }
 ], [
diff --git a/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py b/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
index b1874fc138..a99dc00dc9 100644
--- a/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
+++ b/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
@@ -8,7 +8,7 @@
 import copy
 import os
 import re
-import urlparse
+import six.moves.urllib.parse
 
 from mozharness.base.log import ERROR, WARNING
 from mozharness.base.script import PreScriptAction
@@ -257,7 +257,7 @@ class FirefoxMediaTestsBase(TestingMixin, VCSToolsScript):
             dirs = self.query_abs_dirs()
             manifest_path = os.path.join(dirs['abs_work_dir'], 'releng.manifest')
             try:
-                self.download_file(urlparse.urljoin(url_base, tooltool_manifest),
+                self.download_file(six.moves.urllib.parse.urljoin(url_base, tooltool_manifest),
                                    manifest_path)
             except Exception as e:
                 self.fatal('Download of tooltool manifest file failed: %s' % e.message)
diff --git a/testing/mozharness/mozharness/mozilla/testing/mozpool.py b/testing/mozharness/mozharness/mozilla/testing/mozpool.py
index f9da6c1908..74061ed934 100644
--- a/testing/mozharness/mozharness/mozilla/testing/mozpool.py
+++ b/testing/mozharness/mozharness/mozilla/testing/mozpool.py
@@ -48,7 +48,7 @@ class MozpoolMixin(object):
                 self.MozpoolException = MozpoolException
                 self.MozpoolConflictException = MozpoolConflictException
                 self.mozpool_handler = MozpoolHandler(self.mozpool_api_url, log_obj=self)
-            except ImportError, e:
+            except ImportError as e:
                 self.fatal("Can't instantiate MozpoolHandler until mozpoolclient python "
                            "package is installed! (VirtualenvMixin?): \n%s" % str(e))
             return self.mozpool_handler
@@ -66,7 +66,7 @@ class MozpoolMixin(object):
                 break
             except self.MozpoolConflictException:
                 self.warning("Device unavailable. Retry#%i.." % retry)
-            except self.MozpoolException, e:
+            except self.MozpoolException as e:
                 self.buildbot_status(TBPL_RETRY)
                 self.fatal("We could not request the device: %s" % str(e))
 
@@ -87,7 +87,7 @@ class MozpoolMixin(object):
                 break
             except self.MozpoolConflictException:
                 self.warning("Device unavailable. Retry#%i.." % retry)
-            except self.MozpoolException, e:
+            except self.MozpoolException as e:
                 self.buildbot_status(TBPL_RETRY)
                 self.fatal("We could not request the device: %s" % str(e))
 
diff --git a/testing/mozharness/mozharness/mozilla/testing/talos.py b/testing/mozharness/mozharness/mozilla/testing/talos.py
index 73f384ce7a..2af816095c 100755
--- a/testing/mozharness/mozharness/mozilla/testing/talos.py
+++ b/testing/mozharness/mozharness/mozilla/testing/talos.py
@@ -258,7 +258,7 @@ class Talos(TestingMixin, MercurialScript, BlobUploadMixin):
         kw_options.update(kw)
         # talos expects tests to be in the format (e.g.) 'ts:tp5:tsvg'
         tests = kw_options.get('activeTests')
-        if tests and not isinstance(tests, basestring):
+        if tests and not isinstance(tests, str):
             tests = ':'.join(tests)  # Talos expects this format
             kw_options['activeTests'] = tests
         for key, value in kw_options.items():
diff --git a/testing/mozharness/mozharness/mozilla/testing/testbase.py b/testing/mozharness/mozharness/mozilla/testing/testbase.py
index 2ab2b7e43a..5fd4b75178 100755
--- a/testing/mozharness/mozharness/mozilla/testing/testbase.py
+++ b/testing/mozharness/mozharness/mozilla/testing/testbase.py
@@ -10,7 +10,7 @@ import os
 import platform
 import pprint
 import re
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import json
 import socket
 
@@ -30,6 +30,7 @@ from mozharness.mozilla.testing.try_tools import TryToolsMixin, try_config_optio
 from mozharness.mozilla.tooltool import TooltoolMixin
 
 from mozharness.lib.python.authentication import get_credentials
+import six
 
 INSTALLER_SUFFIXES = ('.apk',  # Android
                       '.tar.bz2', '.tar.gz',  # Linux
@@ -258,7 +259,7 @@ class TestingMixin(VirtualenvMixin, BuildbotMixin, ResourceMonitoringMixin,
         if c.get("test_packages_url"):
             c["test_packages_url"] = _replace_url(c["test_packages_url"], c["replace_urls"])
 
-        for key, value in self.config.iteritems():
+        for key, value in self.config.items():
             if type(value) == str and value.startswith("http"):
                 self.config[key] = _replace_url(value, c["replace_urls"])
 
@@ -281,19 +282,19 @@ class TestingMixin(VirtualenvMixin, BuildbotMixin, ResourceMonitoringMixin,
 
             self.https_username, self.https_password = get_credentials()
             # This creates a password manager
-            passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
+            passman = six.moves.urllib.request.HTTPPasswordMgrWithDefaultRealm()
             # Because we have put None at the start it will use this username/password combination from here on
             passman.add_password(None, url, self.https_username, self.https_password)
-            authhandler = urllib2.HTTPBasicAuthHandler(passman)
+            authhandler = six.moves.urllib.request.HTTPBasicAuthHandler(passman)
 
-            return urllib2.build_opener(authhandler).open(url, **kwargs)
+            return six.moves.urllib.request.build_opener(authhandler).open(url, **kwargs)
 
         # If we have the developer_run flag enabled then we will switch
         # URLs to the right place and enable http authentication
         if "developer_config.py" in self.config["config_files"]:
             return _urlopen_basic_auth(url, **kwargs)
         else:
-            return urllib2.urlopen(url, **kwargs)
+            return six.moves.urllib.request.urlopen(url, **kwargs)
 
     # read_buildbot_config is in BuildbotMixin.
 
@@ -310,7 +311,7 @@ class TestingMixin(VirtualenvMixin, BuildbotMixin, ResourceMonitoringMixin,
             if c.get("require_test_zip") and not self.test_url:
                 expected_length = [2, 3]
             if buildbot_prop_branch.startswith('gaia-try'):
-                expected_length = range(1, 1000)
+                expected_length = list(range(1, 1000))
             actual_length = len(files)
             if actual_length not in expected_length:
                 self.fatal("Unexpected number of files in buildbot config %s.\nExpected these number(s) of files: %s, but got: %d" %
@@ -331,7 +332,7 @@ class TestingMixin(VirtualenvMixin, BuildbotMixin, ResourceMonitoringMixin,
                     if not self.installer_url:
                         self.installer_url = str(f['name'])
                         self.info("Found installer url %s." % self.installer_url)
-        except IndexError, e:
+        except IndexError as e:
             self.error(str(e))
 
     def find_artifacts_from_taskcluster(self):
@@ -734,7 +735,7 @@ Did you run with --create-virtualenv? Is mozinstall in virtualenv_modules?""")
 
         if os.path.exists(abs_nodejs_path):
             if self.platform_name() not in ('win32', 'win64'):
-                self.chmod(abs_nodejs_path, 0755)
+                self.chmod(abs_nodejs_path, 0o755)
             self.nodejs_path = abs_nodejs_path
         else:
             self.warning("nodejs path was given but couldn't be found. Tried looking in '%s'" % abs_nodejs_path)
@@ -774,7 +775,7 @@ Did you run with --create-virtualenv? Is mozinstall in virtualenv_modules?""")
             abs_minidump_path = os.path.join(dirs['abs_work_dir'],
                                              minidump_stackwalk_path)
             if os.path.exists(abs_minidump_path):
-                self.chmod(abs_minidump_path, 0755)
+                self.chmod(abs_minidump_path, 0o755)
                 self.minidump_stackwalk_path = abs_minidump_path
             else:
                 self.warning("minidump stackwalk path was given but couldn't be found. "
diff --git a/testing/mozharness/mozharness/mozilla/testing/try_tools.py b/testing/mozharness/mozharness/mozilla/testing/try_tools.py
index 3708e71db6..85d44be731 100644
--- a/testing/mozharness/mozharness/mozilla/testing/try_tools.py
+++ b/testing/mozharness/mozharness/mozilla/testing/try_tools.py
@@ -188,7 +188,7 @@ class TryToolsMixin(TransferMixin):
                 return label_dict[val]
             return '--%s' % val.replace('_', '-')
 
-        for label, (opts, _) in self.known_try_arguments.iteritems():
+        for label, (opts, _) in self.known_try_arguments.items():
             if 'action' in opts and opts['action'] not in ('append', 'store',
                                                            'store_true', 'store_false'):
                 self.fatal('Try syntax does not support passing custom or store_const '
@@ -207,7 +207,7 @@ class TryToolsMixin(TransferMixin):
         # This is a pretty hacky way to echo arguments down to the harness.
         # Hopefully this can be improved once we have a configuration system
         # in tree for harnesses that relies less on a command line.
-        for arg, value in vars(args).iteritems():
+        for arg, value in vars(args.items()):
             if value:
                 label = label_from_val(arg)
                 _, flavors = self.known_try_arguments[label]
diff --git a/testing/mozharness/mozharness/mozilla/tooltool.py b/testing/mozharness/mozharness/mozilla/tooltool.py
index 0bd98e0a26..2e65b36b67 100644
--- a/testing/mozharness/mozharness/mozilla/tooltool.py
+++ b/testing/mozharness/mozharness/mozilla/tooltool.py
@@ -115,7 +115,7 @@ class TooltoolMixin(object):
         self.download_file(TOOLTOOL_PY_URL, file_path)
         if not os.path.exists(file_path):
             self.fatal("We can't get tooltool.py")
-        self.chmod(file_path, 0755)
+        self.chmod(file_path, 0o755)
         return file_path
 
     def create_tooltool_manifest(self, contents, path=None):
diff --git a/testing/mozharness/mozharness/mozilla/updates/balrog.py b/testing/mozharness/mozharness/mozilla/updates/balrog.py
index 26253283cf..fe0fc814df 100644
--- a/testing/mozharness/mozharness/mozilla/updates/balrog.py
+++ b/testing/mozharness/mozharness/mozilla/updates/balrog.py
@@ -20,13 +20,13 @@ class BalrogMixin(object):
         )
 
         if self.buildbot_config and "properties" in self.buildbot_config:
-            buildbot_properties = self.buildbot_config["properties"].items()
+            buildbot_properties = list(self.buildbot_config["properties"].items())
         else:
             buildbot_properties = []
 
         balrog_props = dict(properties=dict(chain(
             buildbot_properties,
-            self.buildbot_properties.items(),
+            list(self.buildbot_properties.items()),
         )))
         if self.config.get('balrog_platform'):
             balrog_props["properties"]["platform"] = self.config['balrog_platform']
diff --git a/testing/mozharness/mozharness/mozilla/vcstools.py b/testing/mozharness/mozharness/mozilla/vcstools.py
index b73a4767d8..1c11fdc842 100644
--- a/testing/mozharness/mozharness/mozilla/vcstools.py
+++ b/testing/mozharness/mozharness/mozilla/vcstools.py
@@ -34,7 +34,7 @@ class VCSToolsScript(VCSScript):
                         parent_dir=os.path.dirname(file_path),
                         create_parent_dir=True,
                     )
-                    self.chmod(file_path, 0755)
+                    self.chmod(file_path, 0o755)
         else:
             # We simply verify that everything is in order
             # or if the user forgot to specify developer mode
diff --git a/testing/mozharness/mozinfo/__init__.py b/testing/mozharness/mozinfo/__init__.py
index 904dfef71a..e45d71ff87 100644
--- a/testing/mozharness/mozinfo/__init__.py
+++ b/testing/mozharness/mozinfo/__init__.py
@@ -51,6 +51,6 @@ Module variables:
 
 """
 
-import mozinfo
-from mozinfo import *
+from . import mozinfo
+from .mozinfo import *
 __all__ = mozinfo.__all__
diff --git a/testing/mozharness/mozinfo/mozinfo.py b/testing/mozharness/mozinfo/mozinfo.py
index 718e1a9d7a..7aa897a401 100755
--- a/testing/mozharness/mozinfo/mozinfo.py
+++ b/testing/mozharness/mozinfo/mozinfo.py
@@ -8,6 +8,7 @@
 # linux) to the information; I certainly wouldn't want anyone parsing this
 # information and having behaviour depend on it
 
+from __future__ import print_function
 import json
 import os
 import platform
@@ -111,7 +112,7 @@ def update(new_info):
                      to a json file containing the new info.
     """
 
-    if isinstance(new_info, basestring):
+    if isinstance(new_info, str):
         f = mozfile.load(new_info)
         new_info = json.loads(f.read())
         f.close()
@@ -161,7 +162,7 @@ def find_and_update_from_json(*dirs):
 update({})
 
 # exports
-__all__ = info.keys()
+__all__ = list(info.keys())
 __all__ += ['is' + os_name.title() for os_name in choices['os']]
 __all__ += [
     'info',
@@ -187,7 +188,7 @@ def main(args=None):
     if args:
         for arg in args:
             if _os.path.exists(arg):
-                string = file(arg).read()
+                string = open(arg).read()
             else:
                 string = arg
             update(json.loads(string))
@@ -196,14 +197,14 @@ def main(args=None):
     flag = False
     for key, value in options.__dict__.items():
         if value is True:
-            print '%s choices: %s' % (key, ' '.join([str(choice)
-                                                     for choice in choices[key]]))
+            print('%s choices: %s' % (key, ' '.join([str(choice)
+                                                     for choice in choices[key]])))
             flag = True
     if flag: return
 
     # otherwise, print out all info
     for key, value in info.items():
-        print '%s: %s' % (key, value)
+        print('%s: %s' % (key, value))
 
 if __name__ == '__main__':
     main()
diff --git a/testing/mozharness/mozprocess/__init__.py b/testing/mozharness/mozprocess/__init__.py
index 6f4ae49450..02935d078d 100644
--- a/testing/mozharness/mozprocess/__init__.py
+++ b/testing/mozharness/mozprocess/__init__.py
@@ -2,4 +2,4 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from processhandler import *
+from .processhandler import *
diff --git a/testing/mozharness/mozprocess/pid.py b/testing/mozharness/mozprocess/pid.py
index d1f0d93368..d9a943d560 100755
--- a/testing/mozharness/mozprocess/pid.py
+++ b/testing/mozharness/mozprocess/pid.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import mozinfo
 import shlex
@@ -75,7 +76,7 @@ def get_pids(name):
 
     if mozinfo.isWin:
         # use the windows-specific implementation
-        import wpk
+        from . import wpk
         return wpk.get_pids(name)
     else:
         return [pid for pid,_ in running_processes(name)]
@@ -85,4 +86,4 @@ if __name__ == '__main__':
     for i in sys.argv[1:]:
         pids.update(get_pids(i))
     for i in sorted(pids):
-        print i
+        print(i)
diff --git a/testing/mozharness/mozprocess/processhandler.py b/testing/mozharness/mozprocess/processhandler.py
index b89e17eb03..71c0d73592 100644
--- a/testing/mozharness/mozprocess/processhandler.py
+++ b/testing/mozharness/mozprocess/processhandler.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import select
 import signal
@@ -10,7 +11,7 @@ import sys
 import threading
 import time
 import traceback
-from Queue import Queue
+from queue import Queue
 from datetime import datetime, timedelta
 __all__ = ['ProcessHandlerMixin', 'ProcessHandler']
 
@@ -24,8 +25,8 @@ isPosix = os.name == "posix" # includes MacOS X
 if isWin:
     import ctypes, ctypes.wintypes, msvcrt
     from ctypes import sizeof, addressof, c_ulong, byref, POINTER, WinError, c_longlong
-    import winprocess
-    from qijo import JobObjectAssociateCompletionPortInformation,\
+    from . import winprocess
+    from .qijo import JobObjectAssociateCompletionPortInformation,\
     JOBOBJECT_ASSOCIATE_COMPLETION_PORT, JobObjectExtendedLimitInformation,\
     JOBOBJECT_BASIC_LIMIT_INFORMATION, JOBOBJECT_EXTENDED_LIMIT_INFORMATION, IO_COUNTERS
 
@@ -94,17 +95,17 @@ class ProcessHandlerMixin(object):
                                           preexec_fn, close_fds,
                                           shell, cwd, env,
                                           universal_newlines, startupinfo, creationflags)
-            except OSError, e:
-                print >> sys.stderr, args
+            except OSError as e:
+                print(args, file=sys.stderr)
                 raise
 
-        def __del__(self, _maxint=sys.maxint):
+        def __del__(self, _maxint=sys.maxsize):
             if isWin:
                 if self._handle:
                     if hasattr(self, '_internal_poll'):
                         self._internal_poll(_deadstate=_maxint)
                     else:
-                        self.poll(_deadstate=sys.maxint)
+                        self.poll(_deadstate=sys.maxsize)
                 if self._handle or self._job or self._io_port:
                     self._cleanup()
             else:
@@ -131,10 +132,10 @@ class ProcessHandlerMixin(object):
                 if not self._ignore_children:
                     try:
                         os.killpg(self.pid, sig)
-                    except BaseException, e:
+                    except BaseException as e:
                         if getattr(e, "errno", None) != 3:
                             # Error 3 is "no such process", which is ok
-                            print >> sys.stdout, "Could not kill process, could not find pid: %s, assuming it's already dead" % self.pid
+                            print("Could not kill process, could not find pid: %s, assuming it's already dead" % self.pid, file=sys.stdout)
                 else:
                     os.kill(self.pid, sig)
                 self.returncode = -sig
@@ -174,7 +175,7 @@ class ProcessHandlerMixin(object):
                      p2cread, p2cwrite,
                      c2pread, c2pwrite,
                      errread, errwrite) = args_tuple
-                if not isinstance(args, basestring):
+                if not isinstance(args, str):
                     args = subprocess.list2cmdline(args)
 
                 # Always or in the create new process group
@@ -201,7 +202,7 @@ class ProcessHandlerMixin(object):
                 if not canCreateJob and not self._ignore_children:
                     # We can't create job objects AND the user wanted us to
                     # Warn the user about this.
-                    print >> sys.stderr, "ProcessManager UNABLE to use job objects to manage child processes"
+                    print("ProcessManager UNABLE to use job objects to manage child processes", file=sys.stderr)
 
                 # set process creation flags
                 creationflags |= winprocess.CREATE_SUSPENDED
@@ -211,7 +212,7 @@ class ProcessHandlerMixin(object):
                 else:
                     # Since we've warned, we just log info here to inform you
                     # of the consequence of setting ignore_children = True
-                    print "ProcessManager NOT managing child processes"
+                    print("ProcessManager NOT managing child processes")
 
                 # create the process
                 hp, ht, pid, tid = winprocess.CreateProcess(
@@ -283,10 +284,10 @@ class ProcessHandlerMixin(object):
                         # Spin up our thread for managing the IO Completion Port
                         self._procmgrthread = threading.Thread(target = self._procmgr)
                     except:
-                        print >> sys.stderr, """Exception trying to use job objects;
-falling back to not using job objects for managing child processes"""
+                        print("""Exception trying to use job objects;
+falling back to not using job objects for managing child processes""", file=sys.stderr)
                         tb = traceback.format_exc()
-                        print >> sys.stderr, tb
+                        print(tb, file=sys.stderr)
                         # Ensure no dangling handles left behind
                         self._cleanup_job_io_port()
                 else:
@@ -318,7 +319,7 @@ falling back to not using job objects for managing child processes"""
                 countdowntokill = 0
 
                 if MOZPROCESS_DEBUG:
-                    print "DBG::MOZPROC Self.pid value is: %s" % self.pid
+                    print("DBG::MOZPROC Self.pid value is: %s" % self.pid)
 
                 while True:
                     msgid = c_ulong(0)
@@ -340,9 +341,9 @@ falling back to not using job objects for managing child processes"""
                         # don't want to mistake that situation for the situation of an unexpected
                         # parent abort (which is what we're looking for here).
                         if diff.seconds > self.MAX_IOCOMPLETION_PORT_NOTIFICATION_DELAY:
-                            print >> sys.stderr, "Parent process %s exited with children alive:" % self.pid
-                            print >> sys.stderr, "PIDS: %s" %  ', '.join([str(i) for i in self._spawned_procs])
-                            print >> sys.stderr, "Attempting to kill them..."
+                            print("Parent process %s exited with children alive:" % self.pid, file=sys.stderr)
+                            print("PIDS: %s" %  ', '.join([str(i) for i in self._spawned_procs]), file=sys.stderr)
+                            print("Attempting to kill them...", file=sys.stderr)
                             self.kill()
                             self._process_events.put({self.pid: 'FINISHED'})
 
@@ -351,19 +352,19 @@ falling back to not using job objects for managing child processes"""
                         errcode = winprocess.GetLastError()
                         if errcode == winprocess.ERROR_ABANDONED_WAIT_0:
                             # Then something has killed the port, break the loop
-                            print >> sys.stderr, "IO Completion Port unexpectedly closed"
+                            print("IO Completion Port unexpectedly closed", file=sys.stderr)
                             break
                         elif errcode == winprocess.WAIT_TIMEOUT:
                             # Timeouts are expected, just keep on polling
                             continue
                         else:
-                            print >> sys.stderr, "Error Code %s trying to query IO Completion Port, exiting" % errcode
+                            print("Error Code %s trying to query IO Completion Port, exiting" % errcode, file=sys.stderr)
                             raise WinError(errcode)
                             break
 
                     if compkey.value == winprocess.COMPKEY_TERMINATE.value:
                         if MOZPROCESS_DEBUG:
-                            print "DBG::MOZPROC compkeyterminate detected"
+                            print("DBG::MOZPROC compkeyterminate detected")
                         # Then we're done
                         break
 
@@ -373,7 +374,7 @@ falling back to not using job objects for managing child processes"""
                             # No processes left, time to shut down
                             # Signal anyone waiting on us that it is safe to shut down
                             if MOZPROCESS_DEBUG:
-                                print "DBG::MOZPROC job object msg active processes zero"
+                                print("DBG::MOZPROC job object msg active processes zero")
                             self._process_events.put({self.pid: 'FINISHED'})
                             break
                         elif msgid.value == winprocess.JOB_OBJECT_MSG_NEW_PROCESS:
@@ -383,10 +384,10 @@ falling back to not using job objects for managing child processes"""
                             if pid.value != self.pid:
                                 self._spawned_procs[pid.value] = 1
                                 if MOZPROCESS_DEBUG:
-                                    print "DBG::MOZPROC new process detected with pid value: %s" % pid.value
+                                    print("DBG::MOZPROC new process detected with pid value: %s" % pid.value)
                         elif msgid.value == winprocess.JOB_OBJECT_MSG_EXIT_PROCESS:
                             if MOZPROCESS_DEBUG:
-                                print "DBG::MOZPROC process id %s exited normally" % pid.value
+                                print("DBG::MOZPROC process id %s exited normally" % pid.value)
                             # One process exited normally
                             if pid.value == self.pid and len(self._spawned_procs) > 0:
                                 # Parent process dying, start countdown timer
@@ -397,7 +398,7 @@ falling back to not using job objects for managing child processes"""
                         elif msgid.value == winprocess.JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
                             # One process existed abnormally
                             if MOZPROCESS_DEBUG:
-                                print "DBG::MOZPROC process id %s existed abnormally" % pid.value
+                                print("DBG::MOZPROC process id %s existed abnormally" % pid.value)
                             if pid.value == self.pid and len(self._spawned_procs) > 0:
                                 # Parent process dying, start countdown timer
                                 countdowntokill = datetime.now()
@@ -407,7 +408,7 @@ falling back to not using job objects for managing child processes"""
                         else:
                             # We don't care about anything else
                             if MOZPROCESS_DEBUG:
-                                print "DBG::MOZPROC We got a message %s" % msgid.value
+                                print("DBG::MOZPROC We got a message %s" % msgid.value)
                             pass
 
             def _wait(self):
@@ -457,7 +458,7 @@ falling back to not using job objects for managing child processes"""
                     # is call waitforsingleobject and hope for the best
 
                     if MOZPROCESS_DEBUG and not self._ignore_children:
-                        print "DBG::MOZPROC NOT USING JOB OBJECTS!!!"
+                        print("DBG::MOZPROC NOT USING JOB OBJECTS!!!")
                     # First, make sure we have not already ended
                     if self.returncode != winprocess.STILL_ACTIVE:
                         self._cleanup()
@@ -469,11 +470,11 @@ falling back to not using job objects for managing child processes"""
 
                     if rc == winprocess.WAIT_TIMEOUT:
                         # The process isn't dead, so kill it
-                        print "Timed out waiting for process to close, attempting TerminateProcess"
+                        print("Timed out waiting for process to close, attempting TerminateProcess")
                         self.kill()
                     elif rc == winprocess.WAIT_OBJECT_0:
                         # We caught WAIT_OBJECT_0, which indicates all is well
-                        print "Single process terminated successfully"
+                        print("Single process terminated successfully")
                         self.returncode = winprocess.GetExitCodeProcess(self._handle)
                     else:
                         # An error occured we should probably throw
@@ -546,11 +547,11 @@ falling back to not using job objects for managing child processes"""
                         if status > 255:
                             return status >> 8
                         return -status
-                    except OSError, e:
+                    except OSError as e:
                         if getattr(e, "errno", None) != 10:
                             # Error 10 is "no child process", which could indicate normal
                             # close
-                            print >> sys.stderr, "Encountered error waiting for pid to close: %s" % e
+                            print("Encountered error waiting for pid to close: %s" % e, file=sys.stderr)
                             raise
                         return 0
 
@@ -564,7 +565,7 @@ falling back to not using job objects for managing child processes"""
 
         else:
             # An unrecognized platform, we will call the base class for everything
-            print >> sys.stderr, "Unrecognized platform, process groups may not be managed properly"
+            print("Unrecognized platform, process groups may not be managed properly", file=sys.stderr)
 
             def _wait(self):
                 self.returncode = subprocess.Popen.wait(self)
@@ -672,7 +673,7 @@ falling back to not using job objects for managing child processes"""
         except AttributeError:
             # Try to print a relevant error message.
             if not self.proc:
-                print >> sys.stderr, "Unable to kill Process because call to ProcessHandler constructor failed."
+                print("Unable to kill Process because call to ProcessHandler constructor failed.", file=sys.stderr)
             else:
                 raise
 
@@ -782,8 +783,8 @@ falling back to not using job objects for managing child processes"""
 
     # TODO Remove this method when consumers have been fixed
     def waitForFinish(self, timeout=None):
-        print >> sys.stderr, "MOZPROCESS WARNING: ProcessHandler.waitForFinish() is deprecated, " \
-                             "use ProcessHandler.wait() instead"
+        print("MOZPROCESS WARNING: ProcessHandler.waitForFinish() is deprecated, " \
+                             "use ProcessHandler.wait() instead", file=sys.stderr)
         return self.wait(timeout=timeout)
 
 
@@ -855,7 +856,7 @@ falling back to not using job objects for managing child processes"""
 ### these should be callables that take the output line
 
 def print_output(line):
-    print line
+    print(line)
 
 class StoreOutput(object):
     """accumulate stdout"""
@@ -875,7 +876,7 @@ class LogOutput(object):
 
     def __call__(self, line):
         if self.file is None:
-            self.file = file(self.filename, 'a')
+            self.file = open(self.filename, 'a')
         self.file.write(line + '\n')
         self.file.flush()
 
diff --git a/testing/mozharness/mozprocess/qijo.py b/testing/mozharness/mozprocess/qijo.py
index 1ac88430ce..1da1cfcee5 100644
--- a/testing/mozharness/mozprocess/qijo.py
+++ b/testing/mozharness/mozprocess/qijo.py
@@ -77,7 +77,7 @@ class JobObjectInfo(object):
                    9: JOBOBJECT_EXTENDED_LIMIT_INFORMATION
                    }
     def __init__(self, _class):
-        if isinstance(_class, basestring):
+        if isinstance(_class, str):
             assert _class in self.mapping, 'Class should be one of %s; you gave %s' % (self.mapping, _class)
             _class = self.mapping[_class]
         assert _class in self.structures, 'Class should be one of %s; you gave %s' % (self.structures, _class)
diff --git a/testing/mozharness/mozprocess/winprocess.py b/testing/mozharness/mozprocess/winprocess.py
index 6f3afc8de3..68a539216e 100644
--- a/testing/mozharness/mozprocess/winprocess.py
+++ b/testing/mozharness/mozprocess/winprocess.py
@@ -34,9 +34,10 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+from __future__ import print_function
 from ctypes import c_void_p, POINTER, sizeof, Structure, Union, windll, WinError, WINFUNCTYPE, c_ulong
 from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WORD, ULONG
-from qijo import QueryInformationJobObject
+from .qijo import QueryInformationJobObject
 
 LPVOID = c_void_p
 LPBYTE = POINTER(BYTE)
@@ -140,7 +141,7 @@ class EnvironmentBlock:
             self._as_parameter_ = None
         else:
             values = ["%s=%s" % (key, value)
-                      for (key, value) in dict.iteritems()]
+                      for (key, value) in dict.items()]
             values.append("")
             self._as_parameter_ = LPCWSTR("\0".join(values))
 
@@ -426,32 +427,32 @@ def CanCreateJobObject():
 ### testing functions
 
 def parent():
-    print 'Starting parent'
+    print('Starting parent')
     currentProc = GetCurrentProcess()
     if IsProcessInJob(currentProc):
-        print >> sys.stderr, "You should not be in a job object to test"
+        print("You should not be in a job object to test", file=sys.stderr)
         sys.exit(1)
     assert CanCreateJobObject()
-    print 'File: %s' % __file__
+    print('File: %s' % __file__)
     command = [sys.executable, __file__, '-child']
-    print 'Running command: %s' % command
+    print('Running command: %s' % command)
     process = Popen(command)
     process.kill()
     code = process.returncode
-    print 'Child code: %s' % code
+    print('Child code: %s' % code)
     assert code == 127
         
 def child():
-    print 'Starting child'
+    print('Starting child')
     currentProc = GetCurrentProcess()
     injob = IsProcessInJob(currentProc)
-    print "Is in a job?: %s" % injob
+    print("Is in a job?: %s" % injob)
     can_create = CanCreateJobObject()
-    print 'Can create job?: %s' % can_create
+    print('Can create job?: %s' % can_create)
     process = Popen('c:\\windows\\notepad.exe')
     assert process._job
     jobinfo = QueryInformationJobObject(process._job, 'JobObjectExtendedLimitInformation')
-    print 'Job info: %s' % jobinfo
+    print('Job info: %s' % jobinfo)
     limitflags = jobinfo['BasicLimitInformation']['LimitFlags']
-    print 'LimitFlags: %s' % limitflags
+    print('LimitFlags: %s' % limitflags)
     process.kill()
diff --git a/testing/mozharness/scripts/android_emulator_unittest.py b/testing/mozharness/scripts/android_emulator_unittest.py
index 84c5447ed3..2f7a48bebc 100644
--- a/testing/mozharness/scripts/android_emulator_unittest.py
+++ b/testing/mozharness/scripts/android_emulator_unittest.py
@@ -298,7 +298,7 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
                 telnet_ok = True
             else:
                 self.warning('Unable to connect to port %d' % port)
-        except socket.error, e:
+        except socket.error as e:
             self.info('Trying again after socket error: %s' % str(e))
             pass
         except EOFError:
@@ -398,7 +398,7 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
             os.close(tmpfd)
             self.info("Taking screenshot with %s; saving to %s" % (utility, filename))
             subprocess.call([utility, filename], env=self.query_env())
-        except OSError, err:
+        except OSError as err:
             self.warning("Failed to take screenshot: %s" % err.strerror)
 
     def _query_package_name(self):
diff --git a/testing/mozharness/scripts/configtest.py b/testing/mozharness/scripts/configtest.py
index 5db684f0a7..baa15ed4c1 100755
--- a/testing/mozharness/scripts/configtest.py
+++ b/testing/mozharness/scripts/configtest.py
@@ -118,7 +118,7 @@ class ConfigTest(BaseScript):
                 global_dict = {}
                 local_dict = {}
                 try:
-                    execfile(config_file, global_dict, local_dict)
+                    exec(compile(open(config_file, "rb").read(), config_file, 'exec'), global_dict, local_dict)
                 except:
                     self.add_summary("%s is invalid python." % config_file,
                                      level="error")
diff --git a/testing/mozharness/scripts/desktop_l10n.py b/testing/mozharness/scripts/desktop_l10n.py
index 0626ce35b5..cbb7f6ba48 100755
--- a/testing/mozharness/scripts/desktop_l10n.py
+++ b/testing/mozharness/scripts/desktop_l10n.py
@@ -623,7 +623,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
 
         for repository in config['repos']:
             current_repo = {}
-            for key, value in repository.iteritems():
+            for key, value in repository.items():
                 try:
                     current_repo[key] = value % replace_dict
                 except TypeError:
@@ -1051,7 +1051,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
     def taskcluster_upload(self):
         auth = os.path.join(os.getcwd(), self.config['taskcluster_credentials_file'])
         credentials = {}
-        execfile(auth, credentials)
+        exec(compile(open(auth, "rb").read(), auth, 'exec'), credentials)
         client_id = credentials.get('taskcluster_clientId')
         access_token = credentials.get('taskcluster_accessToken')
         if not client_id or not access_token:
@@ -1095,7 +1095,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
             artifacts_task = artifacts_tc.get_task(artifacts_task_id)
             artifacts_tc.claim_task(artifacts_task)
 
-        for locale, files in self.upload_files.iteritems():
+        for locale, files in self.upload_files.items():
             self.info("Uploading files to S3 for locale '%s': %s" % (locale, files))
             routes = []
             for template in templates:
diff --git a/testing/mozharness/scripts/desktop_partner_repacks.py b/testing/mozharness/scripts/desktop_partner_repacks.py
index ff07dffc84..570675f811 100755
--- a/testing/mozharness/scripts/desktop_partner_repacks.py
+++ b/testing/mozharness/scripts/desktop_partner_repacks.py
@@ -162,7 +162,7 @@ class DesktopPartnerRepacks(ReleaseMixin, BuildbotMixin, PurgeMixin,
                                   error_level=FATAL)
         if not os.path.exists(repo):
             self.fatal("Unable to download repo tool.")
-        self.chmod(repo, 0755)
+        self.chmod(repo, 0o755)
         self.retry(self._repo_init,
                    args=(repo,),
                    error_level=FATAL,
diff --git a/testing/mozharness/scripts/desktop_unittest.py b/testing/mozharness/scripts/desktop_unittest.py
index b2e7545671..31bd3a808c 100755
--- a/testing/mozharness/scripts/desktop_unittest.py
+++ b/testing/mozharness/scripts/desktop_unittest.py
@@ -451,7 +451,7 @@ class DesktopUnittest(TestingMixin, MercurialScript, BlobUploadMixin, MozbaseMix
                 # suites gets a dict of everything from all_suites where a key
                 # is also in specified_suites
                 suites = dict((key, all_suites.get(key)) for key in
-                              specified_suites if key in all_suites.keys())
+                              specified_suites if key in list(all_suites.keys()))
         else:
             if c.get('run_all_suites'):  # needed if you dont specify any suites
                 suites = all_suites
diff --git a/testing/mozharness/scripts/firefox_ui_tests/update_release.py b/testing/mozharness/scripts/firefox_ui_tests/update_release.py
index f1ec816463..055dbbb749 100755
--- a/testing/mozharness/scripts/firefox_ui_tests/update_release.py
+++ b/testing/mozharness/scripts/firefox_ui_tests/update_release.py
@@ -10,7 +10,7 @@ import copy
 import os
 import pprint
 import sys
-import urllib
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
 
 # load modules from parent dir
 sys.path.insert(1, os.path.dirname(os.path.dirname(sys.path[0])))
@@ -239,7 +239,7 @@ class ReleaseFirefoxUIUpdateTests(FirefoxUIUpdateTests):
                 # Determine from where to download the file
                 installer_url = '{server}/{fragment}'.format(
                     server=rel_info['ftp_server_from'],
-                    fragment=urllib.quote(rel_info['from'].replace('%locale%', locale))
+                    fragment=six.moves.urllib.parse.quote(rel_info['from'].replace('%locale%', locale))
                 )
                 installer_path = self.download_file(
                     url=installer_url,
diff --git a/testing/mozharness/scripts/gaia_unit.py b/testing/mozharness/scripts/gaia_unit.py
index 660643b742..8eac51b64a 100755
--- a/testing/mozharness/scripts/gaia_unit.py
+++ b/testing/mozharness/scripts/gaia_unit.py
@@ -5,6 +5,7 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 # ***** END LICENSE BLOCK *****
 
+from __future__ import print_function
 import os
 import sys
 import glob
@@ -68,7 +69,7 @@ class GaiaUnitTest(GaiaTest):
                     try:
                         disabled_tests = json.loads(m.read())
                     except:
-                        print "Error while decoding disabled.json; please make sure this file has valid JSON syntax."
+                        print("Error while decoding disabled.json; please make sure this file has valid JSON syntax.")
                         sys.exit(1)
 
                 # Construct a list of all tests
@@ -76,10 +77,10 @@ class GaiaUnitTest(GaiaTest):
                 for path in ('apps', 'tv_apps'):
                     test_root    = os.path.join(dirs['abs_gaia_dir'], path)
                     full_paths   = glob.glob(os.path.join(test_root, '*/test/unit/*_test.js'))
-                    unit_tests  += map(lambda x: os.path.relpath(x, test_root), full_paths)
+                    unit_tests  += [os.path.relpath(x, test_root) for x in full_paths]
 
                 # Remove the tests that are disabled
-                active_unit_tests = filter(lambda x: x not in disabled_tests, unit_tests)
+                active_unit_tests = [x for x in unit_tests if x not in disabled_tests]
 
                 # Chunk the list as requested
                 tests_to_run = subprocess.check_output(chunker + active_unit_tests).strip().split(' ')
diff --git a/testing/mozharness/scripts/merge_day/gecko_migration.py b/testing/mozharness/scripts/merge_day/gecko_migration.py
index 7208630e0f..7c178a97d4 100755
--- a/testing/mozharness/scripts/merge_day/gecko_migration.py
+++ b/testing/mozharness/scripts/merge_day/gecko_migration.py
@@ -531,7 +531,7 @@ class GeckoMigration(MercurialScript, BalrogMixin, VirtualenvMixin,
         revision = self.query_to_revision()
         # Horrible hack because our internal buildapi interface doesn't let us
         # actually do anything. Need to use the public one w/ auth.
-        username = raw_input("LDAP Username: ")
+        username = input("LDAP Username: ")
         password = getpass(prompt="LDAP Password: ")
         auth = (username, password)
         for builder in self.config["post_merge_builders"]:
diff --git a/testing/mozharness/scripts/mobile_l10n.py b/testing/mozharness/scripts/mobile_l10n.py
index cbac6fa678..048b4be1dd 100755
--- a/testing/mozharness/scripts/mobile_l10n.py
+++ b/testing/mozharness/scripts/mobile_l10n.py
@@ -510,7 +510,7 @@ class MobileSingleLocale(MockMixin, LocalesMixin, ReleaseMixin,
     def taskcluster_upload(self):
         auth = os.path.join(os.getcwd(), self.config['taskcluster_credentials_file'])
         credentials = {}
-        execfile(auth, credentials)
+        exec(compile(open(auth, "rb").read(), auth, 'exec'), credentials)
         client_id = credentials.get('taskcluster_clientId')
         access_token = credentials.get('taskcluster_accessToken')
         if not client_id or not access_token:
diff --git a/testing/mozharness/scripts/release/antivirus.py b/testing/mozharness/scripts/release/antivirus.py
index a28c3fd2f5..ebd95742e9 100644
--- a/testing/mozharness/scripts/release/antivirus.py
+++ b/testing/mozharness/scripts/release/antivirus.py
@@ -130,7 +130,7 @@ class AntivirusScan(BaseScript, VirtualenvMixin):
         from boto.s3.connection import S3Connection
         from boto.exception import S3CopyError, S3ResponseError
         from redo import retry
-        from httplib import HTTPException
+        from six.moves.http_client import HTTPException
 
         # suppress boto debug logging, it's too verbose with --loglevel=debug
         import logging
diff --git a/testing/mozharness/scripts/release/beet_mover.py b/testing/mozharness/scripts/release/beet_mover.py
index 0f3c187530..60b4d549b3 100755
--- a/testing/mozharness/scripts/release/beet_mover.py
+++ b/testing/mozharness/scripts/release/beet_mover.py
@@ -364,7 +364,7 @@ class BeetMover(BaseScript, VirtualenvMixin, object):
     def mime_fix(self):
         """ Add mimetypes for custom extensions """
         mimetypes.init()
-        map(lambda (ext, mime_type,): mimetypes.add_type(mime_type, ext), MIME_MAP.items())
+        list(map(lambda ext_mime_type: mimetypes.add_type(ext_mime_type[1], ext_mime_type[0]), list(MIME_MAP.items())))
 
 if __name__ == '__main__':
     beet_mover = BeetMover(pop_aws_auth_from_env())
diff --git a/testing/mozharness/scripts/release/generate-checksums.py b/testing/mozharness/scripts/release/generate-checksums.py
index 61a1c43d25..d05aab7bbf 100644
--- a/testing/mozharness/scripts/release/generate-checksums.py
+++ b/testing/mozharness/scripts/release/generate-checksums.py
@@ -204,7 +204,7 @@ class ChecksumsGenerator(BaseScript, VirtualenvMixin, SigningMixin, VCSMixin, Bu
         pool.map(worker, find_checksums_files())
 
         for c in raw_checksums:
-            for f, info in parse_checksums_file(c).iteritems():
+            for f, info in parse_checksums_file(c.items()):
                 for pattern in self.config["includes"]:
                     if re.search(pattern, f):
                         if f in self.checksums:
diff --git a/testing/mozharness/scripts/release/postrelease_bouncer_aliases.py b/testing/mozharness/scripts/release/postrelease_bouncer_aliases.py
index 78a60b4bc5..ac7eb8c662 100644
--- a/testing/mozharness/scripts/release/postrelease_bouncer_aliases.py
+++ b/testing/mozharness/scripts/release/postrelease_bouncer_aliases.py
@@ -91,10 +91,10 @@ class PostReleaseBouncerAliases(BaseScript, VirtualenvMixin, BuildbotMixin):
         credentials_file = os.path.join(os.getcwd(),
                                         self.config['credentials_file'])
         credentials = {}
-        execfile(credentials_file, credentials)
+        exec(compile(open(credentials_file, "rb").read(), credentials_file, 'exec'), credentials)
         auth = (credentials['tuxedoUsername'], credentials['tuxedoPassword'])
         version = self.config['version']
-        for product, info in self.config["products"].iteritems():
+        for product, info in self.config["products"].items():
             if "alias" in info:
                 product_template = info["product-name"]
                 related_product = product_template % {"version": version}
diff --git a/testing/mozharness/scripts/release/postrelease_mark_as_shipped.py b/testing/mozharness/scripts/release/postrelease_mark_as_shipped.py
index f84b5771cb..72df206fd1 100644
--- a/testing/mozharness/scripts/release/postrelease_mark_as_shipped.py
+++ b/testing/mozharness/scripts/release/postrelease_mark_as_shipped.py
@@ -90,7 +90,7 @@ class MarkReleaseAsShipped(BaseScript, VirtualenvMixin, BuildbotMixin):
         credentials_file = os.path.join(os.getcwd(),
                                         self.config["credentials_file"])
         credentials = {}
-        execfile(credentials_file, credentials)
+        exec(compile(open(credentials_file, "rb").read(), credentials_file, 'exec'), credentials)
         ship_it_credentials = credentials["ship_it_credentials"]
         auth = (self.config["ship_it_username"],
                 ship_it_credentials.get(self.config["ship_it_username"]))
diff --git a/testing/mozharness/scripts/release/uptake_monitoring.py b/testing/mozharness/scripts/release/uptake_monitoring.py
index 9ec24621f6..9cecaf92da 100644
--- a/testing/mozharness/scripts/release/uptake_monitoring.py
+++ b/testing/mozharness/scripts/release/uptake_monitoring.py
@@ -122,7 +122,7 @@ class UptakeMonitoring(BaseScript, VirtualenvMixin, BuildbotMixin):
         version = self.config["version"]
         dl = []
 
-        for product, info in self.config["products"].iteritems():
+        for product, info in self.config["products"].items():
             if info.get("check_uptake"):
                 product_template = info["product-name"]
                 related_product = product_template % {"version": version}
@@ -137,7 +137,7 @@ class UptakeMonitoring(BaseScript, VirtualenvMixin, BuildbotMixin):
                                                        related_product, bouncer_platform))
         # handle the partials as well
         prev_versions = self.config["partial_versions"]
-        for product, info in self.config["partials"].iteritems():
+        for product, info in self.config["partials"].items():
             if info.get("check_uptake"):
                 product_template = info["product-name"]
                 for prev_version in prev_versions:
@@ -161,7 +161,7 @@ class UptakeMonitoring(BaseScript, VirtualenvMixin, BuildbotMixin):
         credentials_file = os.path.join(os.getcwd(),
                                         self.config["credentials_file"])
         credentials = {}
-        execfile(credentials_file, credentials)
+        exec(compile(open(credentials_file, "rb").read(), credentials_file, 'exec'), credentials)
         auth = (credentials['tuxedoUsername'], credentials['tuxedoPassword'])
         self.info("Starting the loop to determine the uptake monitoring ...")
 
diff --git a/testing/mozharness/scripts/spidermonkey_build.py b/testing/mozharness/scripts/spidermonkey_build.py
index 5522545da5..b474e1aec0 100755
--- a/testing/mozharness/scripts/spidermonkey_build.py
+++ b/testing/mozharness/scripts/spidermonkey_build.py
@@ -22,7 +22,7 @@ from mozharness.mozilla.purge import PurgeMixin
 from mozharness.mozilla.mock import MockMixin
 from mozharness.mozilla.tooltool import TooltoolMixin
 
-SUCCESS, WARNINGS, FAILURE, EXCEPTION, RETRY = xrange(5)
+SUCCESS, WARNINGS, FAILURE, EXCEPTION, RETRY = range(5)
 
 
 def requires(*queries):
diff --git a/testing/mozharness/test/test_base_config.py b/testing/mozharness/test/test_base_config.py
index 42ec7a641d..84784d7bca 100644
--- a/testing/mozharness/test/test_base_config.py
+++ b/testing/mozharness/test/test_base_config.py
@@ -32,7 +32,7 @@ class TestParseConfigFile(unittest.TestCase):
                            output='dict'):
         global_dict = {}
         local_dict = {}
-        execfile(filename, global_dict, local_dict)
+        exec(compile(open(filename, "rb").read(), filename, 'exec'), global_dict, local_dict)
         return local_dict['config']
 
     def test_json_config(self):
diff --git a/testing/mozharness/test/test_base_python.py b/testing/mozharness/test/test_base_python.py
index c013576f07..734dd6345a 100644
--- a/testing/mozharness/test/test_base_python.py
+++ b/testing/mozharness/test/test_base_python.py
@@ -9,7 +9,7 @@ here = os.path.dirname(os.path.abspath(__file__))
 class TestVirtualenvMixin(unittest.TestCase):
     def test_package_versions(self):
         example = os.path.join(here, 'pip-freeze.example.txt')
-        output = file(example).read()
+        output = open(example).read()
         mixin = python.VirtualenvMixin()
         packages = mixin.package_versions(output)
 
diff --git a/testing/mozharness/test/test_base_script.py b/testing/mozharness/test/test_base_script.py
index c069a82f38..47382a68a8 100644
--- a/testing/mozharness/test/test_base_script.py
+++ b/testing/mozharness/test/test_base_script.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import gc
 import mock
 import os
@@ -54,7 +55,7 @@ def get_debug_script_obj():
 
 def _post_fatal(self, **kwargs):
     fh = open('tmpfile_stdout', 'w')
-    print >>fh, test_string
+    print(test_string, file=fh)
     fh.close()
 
 
@@ -100,7 +101,7 @@ class TestScript(unittest.TestCase):
             # now let's see if only unique items were added from each config
             t_override = local_cfg_files.get('test/test_override.py', {})
             self.assertTrue(
-                t_override.get('keep_string') == "don't change me" and len(t_override.keys()) == 1,
+                t_override.get('keep_string') == "don't change me" and len(list(t_override.keys())) == 1,
                 msg="--dump-config-hierarchy dumped wrong keys/value for "
                     "`test/test_override.py`. There should only be one "
                     "item and it should be unique to all the other "
@@ -425,7 +426,7 @@ class TestHelperFunctions(unittest.TestCase):
         win32file.CreateDirectoryExW(u'.', path)
 
         for x in range(0, 20):
-            print("path=%s" % path)
+            print(("path=%s" % path))
             path = path + u'\\%sxxxxxxxxxxxxxxxxxxxx' % x
             win32file.CreateDirectoryExW(u'.', path)
         self.s.rmtree('test_dir')
@@ -445,7 +446,7 @@ class TestHelperFunctions(unittest.TestCase):
     def test_chmod(self):
         self._create_temp_file()
         self.s = script.BaseScript(initial_config_file='test/test.json')
-        self.s.chmod(self.temp_file, 0100700)
+        self.s.chmod(self.temp_file, 0o100700)
         self.assertEqual(os.stat(self.temp_file)[0], 33216,
                          msg="chmod unsuccessful")
 
@@ -694,7 +695,7 @@ class TestRetry(unittest.TestCase):
         args = (1, 'two', 3)
         kwargs = dict(foo='a', bar=7)
         ret = self.s.retry(self._mirrorArgs, args=args, kwargs=kwargs.copy(), sleeptime=0)
-        print ret
+        print(ret)
         self.assertEqual(ret[0], args)
         self.assertEqual(ret[1], kwargs)
 
diff --git a/testing/mozharness/test/test_l10n_locales.py b/testing/mozharness/test/test_l10n_locales.py
index e8372a9fbb..7889a7dbe3 100644
--- a/testing/mozharness/test/test_l10n_locales.py
+++ b/testing/mozharness/test/test_l10n_locales.py
@@ -85,21 +85,21 @@ class TestLocalesMixin(unittest.TestCase):
 
     def test_query_abs_dirs_base(self):
         l = self._get_query_abs_dirs_obj()
-        dirs = l.query_abs_dirs().keys()
+        dirs = list(l.query_abs_dirs().keys())
         dirs.sort()
         self.assertEqual(dirs, self.BASE_ABS_DIRS)
 
     def test_query_abs_dirs_base2(self):
         l = self._get_query_abs_dirs_obj()
-        l.query_abs_dirs().keys()
-        dirs = l.query_abs_dirs().keys()
+        list(l.query_abs_dirs().keys())
+        dirs = list(l.query_abs_dirs().keys())
         dirs.sort()
         self.assertEqual(dirs, self.BASE_ABS_DIRS)
 
     def test_query_abs_dirs_l10n(self):
         l = self._get_query_abs_dirs_obj()
         l.config['l10n_dir'] = "l10n_dir"
-        dirs = l.query_abs_dirs().keys()
+        dirs = list(l.query_abs_dirs().keys())
         dirs.sort()
         expected_dirs = self.BASE_ABS_DIRS + ['abs_l10n_dir']
         expected_dirs.sort()
@@ -110,7 +110,7 @@ class TestLocalesMixin(unittest.TestCase):
         l.config['l10n_dir'] = "l10n_dir"
         l.config['mozilla_dir'] = "mozilla_dir"
         l.config['locales_dir'] = "locales_dir"
-        dirs = l.query_abs_dirs().keys()
+        dirs = list(l.query_abs_dirs().keys())
         dirs.sort()
         expected_dirs = self.BASE_ABS_DIRS + ['abs_mozilla_dir', 'abs_locales_src_dir', 'abs_l10n_dir']
         expected_dirs.sort()
@@ -122,7 +122,7 @@ class TestLocalesMixin(unittest.TestCase):
         l.config['mozilla_dir'] = "mozilla_dir"
         l.config['locales_dir'] = "locales_dir"
         l.config['objdir'] = "objdir"
-        dirs = l.query_abs_dirs().keys()
+        dirs = list(l.query_abs_dirs().keys())
         dirs.sort()
         expected_dirs = self.BASE_ABS_DIRS + ['abs_mozilla_dir', 'abs_locales_src_dir', 'abs_l10n_dir', 'abs_objdir', 'abs_merge_dir', 'abs_locales_dir']
         expected_dirs.sort()
diff --git a/testing/remotecppunittests.py b/testing/remotecppunittests.py
index 197cae8b44..8e4a648cb4 100644
--- a/testing/remotecppunittests.py
+++ b/testing/remotecppunittests.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os, sys
 import subprocess
 import tempfile
@@ -58,7 +59,7 @@ class RemoteCPPUnitTests(cppunittests.CPPUnitTests):
 
                 for info in apk_contents.infolist():
                     if info.filename.endswith(".so"):
-                        print >> sys.stderr, "Pushing %s.." % info.filename
+                        print("Pushing %s.." % info.filename, file=sys.stderr)
                         remote_file = posixpath.join(self.remote_bin_dir, os.path.basename(info.filename))
                         apk_contents.extract(info, tmpdir)
                         local_file = os.path.join(tmpdir, info.filename)
@@ -74,7 +75,7 @@ class RemoteCPPUnitTests(cppunittests.CPPUnitTests):
         elif self.options.local_lib:
             for file in os.listdir(self.options.local_lib):
                 if file.endswith(".so"):
-                    print >> sys.stderr, "Pushing %s.." % file
+                    print("Pushing %s.." % file, file=sys.stderr)
                     remote_file = posixpath.join(self.remote_bin_dir, file)
                     local_file = os.path.join(self.options.local_lib, file)
                     self.device.pushFile(local_file, remote_file)
@@ -85,7 +86,7 @@ class RemoteCPPUnitTests(cppunittests.CPPUnitTests):
                     for root, dirs, files in os.walk(local_arm_lib):
                         for file in files:
                             if (file.endswith(".so")):
-                                print >> sys.stderr, "Pushing %s.." % file
+                                print("Pushing %s.." % file, file=sys.stderr)
                                 remote_file = posixpath.join(self.remote_bin_dir, file)
                                 local_file = os.path.join(root, file)
                                 self.device.pushFile(local_file, remote_file)
@@ -236,7 +237,7 @@ def run_test_harness(options, args):
     else:
         dm = devicemanagerSUT.DeviceManagerSUT(options.device_ip, options.device_port, deviceRoot=options.remote_test_root)
         if not options.device_ip:
-            print "Error: you must provide a device IP to connect to via the --deviceIP option"
+            print("Error: you must provide a device IP to connect to via the --deviceIP option")
             sys.exit(1)
 
     options.xre_path = os.path.abspath(options.xre_path)
@@ -258,23 +259,23 @@ def main():
     mozlog.commandline.add_logging_group(parser)
     options, args = parser.parse_args()
     if not args:
-        print >>sys.stderr, """Usage: %s  [...]""" % sys.argv[0]
+        print("""Usage: %s  [...]""" % sys.argv[0], file=sys.stderr)
         sys.exit(1)
     if options.local_lib is not None and not os.path.isdir(options.local_lib):
-        print >>sys.stderr, """Error: --localLib directory %s not found""" % options.local_lib
+        print("""Error: --localLib directory %s not found""" % options.local_lib, file=sys.stderr)
         sys.exit(1)
     if options.local_apk is not None and not os.path.isfile(options.local_apk):
-        print >>sys.stderr, """Error: --apk file %s not found""" % options.local_apk
+        print("""Error: --apk file %s not found""" % options.local_apk, file=sys.stderr)
         sys.exit(1)
     if not options.xre_path:
-        print >>sys.stderr, """Error: --xre-path is required"""
+        print("""Error: --xre-path is required""", file=sys.stderr)
         sys.exit(1)
 
     log = mozlog.commandline.setup_logging("remotecppunittests", options,
                                            {"tbpl": sys.stdout})
     try:
         result = run_test_harness(options, args)
-    except Exception, e:
+    except Exception as e:
         log.error(str(e))
         result = False
     sys.exit(0 if result else 1)
diff --git a/testing/runcppunittests.py b/testing/runcppunittests.py
index fdd6abc1f6..24612024e0 100755
--- a/testing/runcppunittests.py
+++ b/testing/runcppunittests.py
@@ -5,6 +5,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import with_statement
+from __future__ import print_function
 import sys, os, tempfile, shutil
 from optparse import OptionParser
 import manifestparser
@@ -248,13 +249,13 @@ def main():
     mozlog.commandline.add_logging_group(parser)
     options, args = parser.parse_args()
     if not args:
-        print >>sys.stderr, """Usage: %s  [...]""" % sys.argv[0]
+        print("""Usage: %s  [...]""" % sys.argv[0], file=sys.stderr)
         sys.exit(1)
     if not options.xre_path:
-        print >>sys.stderr, """Error: --xre-path is required"""
+        print("""Error: --xre-path is required""", file=sys.stderr)
         sys.exit(1)
     if options.manifest_path and len(args) > 1:
-        print >>sys.stderr, "Error: multiple arguments not supported with --test-manifest"
+        print("Error: multiple arguments not supported with --test-manifest", file=sys.stderr)
         sys.exit(1)
     log = mozlog.commandline.setup_logging("cppunittests", options,
                                            {"tbpl": sys.stdout})
diff --git a/testing/runtimes/writeruntimes.py b/testing/runtimes/writeruntimes.py
index d67d5b0055..a3edfdd916 100644
--- a/testing/runtimes/writeruntimes.py
+++ b/testing/runtimes/writeruntimes.py
@@ -55,7 +55,7 @@ def write_runtimes(data, suite, indir=here, outdir=here):
 
     # identify a threshold of durations, below which we ignore
     runtimes = []
-    for result in data.itervalues():
+    for result in data.values():
         duration = int(result * 1000) if result else 0
         if duration:
             runtimes.append(duration)
@@ -66,7 +66,7 @@ def write_runtimes(data, suite, indir=here, outdir=here):
     omitted = []
     specified = indata if indata else {}
     current_tests = []
-    for test, duration in data.iteritems():
+    for test, duration in data.items():
         current_tests.append(test)
         duration = int(duration * 1000) if duration else 0
         if duration > 0 and duration < threshold:
diff --git a/testing/talos/INSTALL.py b/testing/talos/INSTALL.py
index debc843f04..32e6c6a1e0 100755
--- a/testing/talos/INSTALL.py
+++ b/testing/talos/INSTALL.py
@@ -10,7 +10,7 @@ installation script for talos. This script:
 import os
 import subprocess
 import sys
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 try:
     from subprocess import check_call as call
 except:
@@ -47,7 +47,7 @@ def main(args=sys.argv[1:]):
                                     '--system-site-packages',
                                     here],
                                    stdin=subprocess.PIPE)
-        stdout, stderr = process.communicate(input=urllib2.urlopen(VIRTUALENV).read())
+        stdout, stderr = process.communicate(input=six.moves.urllib.request.urlopen(VIRTUALENV).read())
 
     # find the virtualenv's python
     for i in ('bin', 'Scripts'):
diff --git a/testing/talos/talos/cmanager_linux.py b/testing/talos/talos/cmanager_linux.py
index 54de636ddc..12419c9730 100644
--- a/testing/talos/talos/cmanager_linux.py
+++ b/testing/talos/talos/cmanager_linux.py
@@ -2,9 +2,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import re
 import subprocess
-from cmanager import CounterManager
+from .cmanager import CounterManager
 
 
 def xrestop(binary='xrestop'):
diff --git a/testing/talos/talos/cmanager_mac.py b/testing/talos/talos/cmanager_mac.py
index fe57778a31..9d1d01b653 100644
--- a/testing/talos/talos/cmanager_mac.py
+++ b/testing/talos/talos/cmanager_mac.py
@@ -4,8 +4,9 @@
 
 """CounterManager for Mac OSX"""
 
+from __future__ import print_function
 import subprocess
-from cmanager import CounterManager
+from .cmanager import CounterManager
 import sys
 
 
@@ -20,7 +21,7 @@ def GetProcessData(pid):
         handle.wait()
         data = handle.stdout.readlines()
     except:
-        print("Unexpected error executing '%s': %s", (command, sys.exc_info()))
+        print(("Unexpected error executing '%s': %s", (command, sys.exc_info())))
         raise
 
     # First line is header output should look like:
@@ -75,12 +76,12 @@ class MacCounterManager(CounterManager):
     def getCounterValue(self, counterName):
         """Returns the last value of the counter 'counterName'"""
         if counterName not in self.registeredCounters:
-            print("Warning: attempting to collect counter %s and it is not"
-                  " registered" % counterName)
+            print(("Warning: attempting to collect counter %s and it is not"
+                  " registered" % counterName))
             return
 
         try:
             return self.registeredCounters[counterName][0](self.pid)
         except Exception as e:
-            print("Error in collecting counter: %s, pid: %s, exception: %s"
-                  % (counterName, self.pid, e))
+            print(("Error in collecting counter: %s, pid: %s, exception: %s"
+                  % (counterName, self.pid, e)))
diff --git a/testing/talos/talos/cmanager_win32.py b/testing/talos/talos/cmanager_win32.py
index cfd215496e..54a9dd135a 100644
--- a/testing/talos/talos/cmanager_win32.py
+++ b/testing/talos/talos/cmanager_win32.py
@@ -2,14 +2,14 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from cmanager import CounterManager
+from .cmanager import CounterManager
 from ctypes import windll
 from ctypes.wintypes import DWORD, HANDLE, LPSTR, LPCSTR, LPCWSTR, Structure, \
     pointer, LONG
 from ctypes import byref, create_string_buffer, memmove, Union, c_double, \
     c_longlong
 import struct
-from utils import TalosError
+from .utils import TalosError
 pdh = windll.pdh
 
 _LONGLONG = c_longlong
diff --git a/testing/talos/talos/cmdline.py b/testing/talos/talos/cmdline.py
index 7d4cd20d9e..864b77d500 100644
--- a/testing/talos/talos/cmdline.py
+++ b/testing/talos/talos/cmdline.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import argparse
 import os
 
@@ -26,14 +27,14 @@ class _ListTests(_StopAction):
         print('================\n')
         test_class_names = [
             (test_class.name(), test_class.description())
-            for test_class in test.test_dict().itervalues()
+            for test_class in test.test_dict(.values())
         ]
         test_class_names.sort()
         for name, description in test_class_names:
             print(name)
-            print('-'*len(name))
+            print(('-'*len(name)))
             print(description)
-            print  # Appends a single blank line to the end
+            print()  # Appends a single blank line to the end
         parser.exit()
 
 
@@ -45,8 +46,8 @@ class _ListSuite(_StopAction):
         max_suite_name = max([len(s) for s in conf])
         pattern = " %%-%ds (%%s)" % max_suite_name
         for name in conf:
-            print(pattern % (name, ':'.join(conf[name]['tests'])))
-        print
+            print((pattern % (name, ':'.join(conf[name]['tests']))))
+        print()
         parser.exit()
 
 
diff --git a/testing/talos/talos/config.py b/testing/talos/talos/config.py
index 4f7b23ab6a..bdc0683684 100644
--- a/testing/talos/talos/config.py
+++ b/testing/talos/talos/config.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import sys
 import os
 import copy
@@ -377,7 +378,7 @@ def get_test(config, global_overrides, counters, test_instance):
             _counters = getattr(test_instance, key)
             _counters.extend([counter for counter in counters
                               if counter not in _counters])
-    return dict(test_instance.items())
+    return dict(list(test_instance.items()))
 
 
 @validator
@@ -462,6 +463,6 @@ def get_configs(argv=None):
 
 if __name__ == '__main__':
     cfgs = get_configs()
-    print(cfgs[0])
-    print
-    print(cfgs[1])
+    print((cfgs[0]))
+    print()
+    print((cfgs[1]))
diff --git a/testing/talos/talos/ffsetup.py b/testing/talos/talos/ffsetup.py
index 14ff576d54..09291634a6 100644
--- a/testing/talos/talos/ffsetup.py
+++ b/testing/talos/talos/ffsetup.py
@@ -61,7 +61,7 @@ class FFSetup(object):
 
     def _init_env(self):
         self.env = dict(os.environ)
-        for k, v in self.browser_config['env'].iteritems():
+        for k, v in self.browser_config['env'].items():
             self.env[k] = str(v)
         self.env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
         # for winxp e10s logging:
diff --git a/testing/talos/talos/mainthreadio.py b/testing/talos/talos/mainthreadio.py
index 112aaace36..52d80cdd6b 100644
--- a/testing/talos/talos/mainthreadio.py
+++ b/testing/talos/talos/mainthreadio.py
@@ -3,9 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
-import utils
-import whitelist
+from . import utils
+from . import whitelist
 
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
 
@@ -86,7 +87,7 @@ def parse(logfilename, data):
                     stage = stage + 1
             return True
     except IOError as e:
-        print("%s: %s" % (e.filename, e.strerror))
+        print(("%s: %s" % (e.filename, e.strerror)))
         return False
 
 
@@ -95,7 +96,7 @@ def write_output(outfilename, data):
     try:
         with open(outfilename, 'w') as outfile:
             outfile.write("[\n")
-            for idx, (key, value) in utils.indexed_items(data.iteritems()):
+            for idx, (key, value) in utils.indexed_items(data.items()):
                 output = "    [\"%s\", \"%s\", \"%s\", \"%s\", %d, %d, %f]" % (
                     key[0], key[1], key[2], key[3], value[KEY_COUNT],
                     value[KEY_RUN_COUNT], value[KEY_DURATION])
@@ -107,17 +108,17 @@ def write_output(outfilename, data):
             outfile.write("]\n")
             return True
     except IOError as e:
-        print("%s: %s" % (e.filename, e.strerror))
+        print(("%s: %s" % (e.filename, e.strerror)))
         return False
 
 
 def main(argv):
     if len(argv) < 4:
-        print("Usage: %s   "
-              % argv[0])
+        print(("Usage: %s   "
+              % argv[0]))
         return 1
     if not os.path.exists(argv[3]):
-        print("XRE Path \"%s\" does not exist" % argv[3])
+        print(("XRE Path \"%s\" does not exist" % argv[3]))
         return 1
     data = {}
     if not parse(argv[1], data):
diff --git a/testing/talos/talos/output.py b/testing/talos/talos/output.py
index 003e98f021..84faf5432a 100755
--- a/testing/talos/talos/output.py
+++ b/testing/talos/talos/output.py
@@ -5,14 +5,14 @@
 
 """output formats for Talos"""
 
-import filter
+from . import filter
 import json
-import utils
+from . import utils
 
 from mozlog import get_proxy_logger
 
 # NOTE: we have a circular dependency with output.py when we import results
-import results as TalosResults
+from . import results as TalosResults
 
 LOG = get_proxy_logger()
 
diff --git a/testing/talos/talos/profiler/symFileManager.py b/testing/talos/talos/profiler/symFileManager.py
index 0413a9ee81..108385e5a2 100755
--- a/testing/talos/talos/profiler/symFileManager.py
+++ b/testing/talos/talos/profiler/symFileManager.py
@@ -2,7 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from symLogging import LogTrace, LogError, LogMessage
+from .symLogging import LogTrace, LogError, LogMessage
 
 import itertools
 import os
@@ -165,7 +165,7 @@ class SymFileManager:
             return None
 
         logString = "Found " + \
-            str(len(symbolMap.keys())) + " unique entries from "
+            str(len(list(symbolMap.keys()))) + " unique entries from "
         logString += str(publicCount) + " PUBLIC lines, " + \
             str(funcCount) + " FUNC lines"
         LogTrace(logString)
diff --git a/testing/talos/talos/profiler/symLogging.py b/testing/talos/talos/profiler/symLogging.py
index 2a6aa89936..b50cce6b24 100755
--- a/testing/talos/talos/profiler/symLogging.py
+++ b/testing/talos/talos/profiler/symLogging.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import sys
 import threading
 import time
@@ -13,17 +14,17 @@ def LogTrace(string):
     global gEnableTracing
     if gEnableTracing:
         threadName = threading.currentThread().getName().ljust(12)
-        print >> sys.stdout, time.asctime() + " " + threadName + " TRACE " + \
-            string
+        print(time.asctime() + " " + threadName + " TRACE " + \
+            string, file=sys.stdout)
 
 
 def LogError(string):
     threadName = threading.currentThread().getName().ljust(12)
-    print >> sys.stderr, time.asctime() + " " + threadName + " ERROR " + \
-        string
+    print(time.asctime() + " " + threadName + " ERROR " + \
+        string, file=sys.stderr)
 
 
 def LogMessage(string):
     threadName = threading.currentThread().getName().ljust(12)
-    print >> sys.stdout, time.asctime() + " " + threadName + "       " + \
-        string
+    print(time.asctime() + " " + threadName + "       " + \
+        string, file=sys.stdout)
diff --git a/testing/talos/talos/profiler/symbolication.py b/testing/talos/talos/profiler/symbolication.py
index 4bb07dfe83..51f8f4a62e 100755
--- a/testing/talos/talos/profiler/symbolication.py
+++ b/testing/talos/talos/profiler/symbolication.py
@@ -9,12 +9,13 @@ import os
 import platform
 import re
 import subprocess
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import zipfile
 from distutils import spawn
-from symFileManager import SymFileManager
-from symbolicationRequest import SymbolicationRequest
-from symLogging import LogMessage
+from .symFileManager import SymFileManager
+from .symbolicationRequest import SymbolicationRequest
+from .symLogging import LogMessage
+import six
 
 """
 Symbolication is broken when using type 'str' in python 2.7, so we use 'basestring'.
@@ -22,9 +23,9 @@ But for python 3.0 compatibility, 'basestring' isn't defined, but the 'str' type
 So we force 'basestring' to 'str'.
 """
 try:
-    basestring
+    str
 except NameError:
-    basestring = str
+    str = str
 
 
 class SymbolError(Exception):
@@ -145,7 +146,7 @@ class ProfileSymbolicator:
         LogMessage("Retrieving symbol zip from {symbol_zip_url}...".format(
             symbol_zip_url=symbol_zip_url))
         try:
-            io = urllib2.urlopen(symbol_zip_url, None, 30)
+            io = six.moves.urllib.request.urlopen(symbol_zip_url, None, 30)
             with zipfile.ZipFile(cStringIO.StringIO(io.read())) as zf:
                 self.integrate_symbol_zip(zf)
             self._create_file_if_not_exists(self._marker_file(symbol_zip_url))
@@ -276,7 +277,7 @@ class ProfileSymbolicator:
             delta_time = profile_start_time - self.main_start_time
 
         for i, thread in enumerate(profile_json["threads"]):
-            if isinstance(thread, basestring):
+            if isinstance(thread, str):
                 thread_json = json.loads(thread)
                 self.symbolicate_profile(thread_json)
                 profile_json["threads"][i] = json.dumps(thread_json)
@@ -307,7 +308,7 @@ class ProfileSymbolicator:
     def _find_addresses_v3(self, profile_json):
         addresses = set()
         for thread in profile_json["threads"]:
-            if isinstance(thread, basestring):
+            if isinstance(thread, str):
                 continue
             for s in thread["stringTable"]:
                 if s[0:2] == "0x":
@@ -316,7 +317,7 @@ class ProfileSymbolicator:
 
     def _substitute_symbols_v3(self, profile_json, symbolication_table):
         for thread in profile_json["threads"]:
-            if isinstance(thread, basestring):
+            if isinstance(thread, str):
                 continue
             for i, s in enumerate(thread["stringTable"]):
                 thread["stringTable"][i] = symbolication_table.get(s, s)
@@ -356,7 +357,7 @@ class ProfileSymbolicator:
                 libs_with_symbols[lib["start"]] = {
                     "library": lib, "symbols": set()}
             libs_with_symbols[lib["start"]]["symbols"].add(address)
-        return libs_with_symbols.values()
+        return list(libs_with_symbols.values())
 
     def _module_from_lib(self, lib):
         if "breakpadId" in lib:
diff --git a/testing/talos/talos/profiler/symbolicationRequest.py b/testing/talos/talos/profiler/symbolicationRequest.py
index 9b5fb0ab2c..f986356c64 100755
--- a/testing/talos/talos/profiler/symbolicationRequest.py
+++ b/testing/talos/talos/profiler/symbolicationRequest.py
@@ -2,11 +2,12 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from symLogging import LogTrace, LogError
+from .symLogging import LogTrace, LogError
 
 import re
 import json
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
+import six
 
 # Precompiled regex for validating lib names
 # Empty lib name means client couldn't associate frame with any lib
@@ -22,9 +23,9 @@ But for python 3.0 compatibility, 'basestring' isn't defined, but the 'str' type
 So we force 'basestring' to 'str'.
 """
 try:
-    basestring
+    str
 except NameError:
-    basestring = str
+    str = str
 
 
 class ModuleV3:
@@ -35,11 +36,11 @@ class ModuleV3:
 
 
 def getModuleV3(libName, breakpadId):
-    if not isinstance(libName, basestring) or not gLibNameRE.match(libName):
+    if not isinstance(libName, str) or not gLibNameRE.match(libName):
         LogTrace("Bad library name: " + str(libName))
         return None
 
-    if not isinstance(breakpadId, basestring):
+    if not isinstance(breakpadId, str):
         LogTrace("Bad breakpad id: " + str(breakpadId))
         return None
 
@@ -202,9 +203,9 @@ class SymbolicationRequest:
                 }
                 requestJson = json.dumps(requestObj)
                 headers = {"Content-Type": "application/json"}
-                requestHandle = urllib2.Request(url, requestJson, headers)
+                requestHandle = six.moves.urllib.request.Request(url, requestJson, headers)
                 try:
-                    response = urllib2.urlopen(requestHandle)
+                    response = six.moves.urllib.request.urlopen(requestHandle)
                 except Exception as e:
                     if requestVersion == 4:
                         # Try again with version 3
diff --git a/testing/talos/talos/results.py b/testing/talos/talos/results.py
index de81ac4902..dabe2d6e17 100755
--- a/testing/talos/talos/results.py
+++ b/testing/talos/talos/results.py
@@ -9,6 +9,7 @@ objects and methods for parsing and serializing Talos results
 see https://wiki.mozilla.org/Buildbot/Talos/DataFormat
 """
 
+from __future__ import print_function
 import json
 import os
 import re
@@ -55,11 +56,11 @@ class TalosResults(object):
                 )
             except:
                 pass
-            print('\nFAIL: %s' % str(e).replace('\n', '\nRETURN:'))
+            print(('\nFAIL: %s' % str(e).replace('\n', '\nRETURN:')))
             raise e
 
         if tbpl_output:
-            print("TinderboxPrint: TalosResult: %s" % json.dumps(tbpl_output))
+            print(("TinderboxPrint: TalosResult: %s" % json.dumps(tbpl_output)))
 
 
 class TestResults(object):
@@ -420,14 +421,14 @@ class BrowserLogResults(object):
         self.mainthread_io(counter_results)
 
         if not set(counters).union(set(mainthread_counters))\
-                .intersection(counter_results.keys()):
+                .intersection(list(counter_results.keys())):
             # no xperf counters to accumulate
             return
 
         filename = 'etl_output_thread_stats.csv'
         if not os.path.exists(filename):
-            print("Warning: we are looking for xperf results file %s, and"
-                  " didn't find it" % filename)
+            print(("Warning: we are looking for xperf results file %s, and"
+                  " didn't find it" % filename))
             return
 
         contents = open(filename).read()
@@ -455,11 +456,11 @@ class BrowserLogResults(object):
                 counter_results.setdefault(counter_name, []).append(value)
                 self.using_xperf = True
 
-        if (set(mainthread_counters).intersection(counter_results.keys())):
+        if (set(mainthread_counters).intersection(list(counter_results.keys()))):
             filename = 'etl_output.csv'
             if not os.path.exists(filename):
-                print("Warning: we are looking for xperf results file"
-                      " %s, and didn't find it" % filename)
+                print(("Warning: we are looking for xperf results file"
+                      " %s, and didn't find it" % filename))
                 return
 
             contents = open(filename).read()
@@ -485,7 +486,7 @@ class BrowserLogResults(object):
 
         counters = ['Main', 'Content']
         if not set(['%s_RSS' % i for i in counters])\
-                .intersection(counter_results.keys()):
+                .intersection(list(counter_results.keys())):
             # no RSS counters to accumulate
             return
         for line in self.results_raw.split('\n'):
diff --git a/testing/talos/talos/run_tests.py b/testing/talos/talos/run_tests.py
index 1e5c3ac508..6161d2a35a 100755
--- a/testing/talos/talos/run_tests.py
+++ b/testing/talos/talos/run_tests.py
@@ -4,13 +4,14 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import mozversion
 import os
 import sys
 import time
 import traceback
-import urllib
-import utils
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
+from . import utils
 import mozhttpd
 
 from mozlog import get_proxy_logger
@@ -40,9 +41,9 @@ def buildCommandLine(test):
 
     # sanity check pageloader values
     # mandatory options: tpmanifest, tpcycles
-    if test['tpcycles'] not in range(1, 1000):
+    if test['tpcycles'] not in list(range(1, 1000)):
         raise TalosError('pageloader cycles must be int 1 to 1,000')
-    if test.get('tpdelay') and test['tpdelay'] not in range(1, 10000):
+    if test.get('tpdelay') and test['tpdelay'] not in list(range(1, 10000)):
         raise TalosError('pageloader delay must be int 1 to 10,000')
     if 'tpmanifest' not in test:
         raise TalosError("tpmanifest not found in test: %s" % test)
@@ -101,7 +102,7 @@ def run_tests(config, browser_config):
                 test[path] = utils.interpolate(test[path])
         if test.get('tpmanifest'):
             test['tpmanifest'] = \
-                os.path.normpath('file:/%s' % (urllib.quote(test['tpmanifest'],
+                os.path.normpath('file:/%s' % (six.moves.urllib.parse.quote(test['tpmanifest'],
                                                '/\\t:\\')))
         if not test.get('url'):
             # build 'url' for tptest
@@ -150,7 +151,7 @@ def run_tests(config, browser_config):
         browser_config['sourcestamp'] = version_info['application_changeset']
     except KeyError:
         if not browser_config['develop']:
-            print("unable to find changeset or repository: %s" % version_info)
+            print(("unable to find changeset or repository: %s" % version_info))
             sys.exit()
         else:
             browser_config['repository'] = 'develop'
@@ -228,8 +229,8 @@ def run_tests(config, browser_config):
     if results_urls:
         talos_results.output(results_urls)
         if browser_config['develop'] or config['sps_profile']:
-            print("Thanks for running Talos locally. Results are in %s"
-                  % (results_urls['output_urls']))
+            print(("Thanks for running Talos locally. Results are in %s"
+                  % (results_urls['output_urls'])))
 
     # we will stop running tests on a failed test, or we will return 0 for
     # green
diff --git a/testing/talos/talos/scripts/report.py b/testing/talos/talos/scripts/report.py
index 7aebc51c60..9bd23a1f6f 100644
--- a/testing/talos/talos/scripts/report.py
+++ b/testing/talos/talos/scripts/report.py
@@ -123,11 +123,11 @@ def main():
     tuple_list = get_all_test_tuples()
     f = 'report'
     if args.platform:
-        tuple_list = filter(lambda x: x[4] == args.platform, tuple_list)
+        tuple_list = [x for x in tuple_list if x[4] == args.platform]
         f += '-%s' % args.platform
 
     if args.test:
-        tuple_list = filter(lambda x: x[3] == args.test, tuple_list)
+        tuple_list = [x for x in tuple_list if x[3] == args.test]
         f += '-%s' % args.test
 
     f += '-%s' % args.mode
diff --git a/testing/talos/talos/talos_process.py b/testing/talos/talos/talos_process.py
index b601240f33..2a553f43d4 100644
--- a/testing/talos/talos/talos_process.py
+++ b/testing/talos/talos/talos_process.py
@@ -10,7 +10,7 @@ from threading import Event
 
 from mozlog import get_proxy_logger
 
-from utils import TalosError
+from .utils import TalosError
 
 LOG = get_proxy_logger()
 
diff --git a/testing/talos/talos/talosconfig.py b/testing/talos/talos/talosconfig.py
index 2645a56bf3..328399cedd 100644
--- a/testing/talos/talos/talosconfig.py
+++ b/testing/talos/talos/talosconfig.py
@@ -1,9 +1,10 @@
+from __future__ import print_function
 import os
 import json
 
 
 def writeConfigFile(obj, vals):
-    data = dict((opt, obj[opt]) for opt in (vals or obj.keys()))
+    data = dict((opt, obj[opt]) for opt in (vals or list(obj.keys())))
     return json.dumps(data)
 
 
diff --git a/testing/talos/talos/test.py b/testing/talos/talos/test.py
index 6df5835bb7..53c8995cd6 100644
--- a/testing/talos/talos/test.py
+++ b/testing/talos/talos/test.py
@@ -65,7 +65,7 @@ class Test(object):
 
     def __str__(self):
         """string form appropriate for YAML output"""
-        items = self.items()
+        items = list(self.items())
 
         key, value = items.pop(0)
         lines = ["- %s: %s" % (key, value)]
diff --git a/testing/talos/talos/ttest.py b/testing/talos/talos/ttest.py
index 3c57f020dd..89a4cc1f54 100644
--- a/testing/talos/talos/ttest.py
+++ b/testing/talos/talos/ttest.py
@@ -12,14 +12,15 @@
      - waits for a 'dump' from the browser
 """
 
+from __future__ import print_function
 import os
 import sys
 import platform
-import results
+from . import results
 import subprocess
-import utils
+from . import utils
 import mozcrash
-import talosconfig
+from . import talosconfig
 import shutil
 import mozfile
 
diff --git a/testing/talos/talos/utils.py b/testing/talos/talos/utils.py
index 2b332d2301..8473cef828 100755
--- a/testing/talos/talos/utils.py
+++ b/testing/talos/talos/utils.py
@@ -6,9 +6,9 @@
 
 import os
 import time
-import urlparse
+import six.moves.urllib.parse
 import string
-import urllib
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
 import json
 import re
 import platform
@@ -136,7 +136,7 @@ def urlsplit(url, default_scheme='file'):
         return ['file', '', url[len('file://'):], '', '']
 
     # split the URL and return a list
-    return [i for i in urlparse.urlsplit(url)]
+    return [i for i in six.moves.urllib.parse.urlsplit(url)]
 
 
 def parse_pref(value):
@@ -170,9 +170,9 @@ def GenerateBrowserCommandLine(browser_path, extra_args, profile_dir,
             command_args.extend(['-tpprofilinginfo',
                                  json.dumps(profiling_info)])
         elif url.find('?') != -1:
-            url += '&' + urllib.urlencode(profiling_info)
+            url += '&' + six.moves.urllib.parse.urlencode(profiling_info)
         else:
-            url += '?' + urllib.urlencode(profiling_info)
+            url += '?' + six.moves.urllib.parse.urlencode(profiling_info)
 
     command_args.extend(url.split(' '))
 
@@ -184,7 +184,7 @@ def indexed_items(itr):
     Generator that allows us to figure out which item is the last one so
     that we can serialize this data properly
     """
-    prev_i, prev_val = 0, itr.next()
+    prev_i, prev_val = 0, next(itr)
     for i, val in enumerate(itr, start=1):
         yield prev_i, prev_val
         prev_i, prev_val = i, val
diff --git a/testing/talos/talos/whitelist.py b/testing/talos/talos/whitelist.py
index 1e4c4117eb..7d07095152 100644
--- a/testing/talos/talos/whitelist.py
+++ b/testing/talos/talos/whitelist.py
@@ -3,9 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import json
 import os
-import utils
+from . import utils
 
 KEY_XRE = '{xre}'
 DEFAULT_DURATION = 100.0
@@ -37,7 +38,7 @@ class Whitelist:
                 self.listmap[whitelist_name.lower()] = temp[whitelist_name]
 
         except IOError as e:
-            print("%s: %s" % (e.filename, e.strerror))
+            print(("%s: %s" % (e.filename, e.strerror)))
             return False
         return True
 
@@ -45,7 +46,7 @@ class Whitelist:
         filename = filename.lower()
         filename.replace(' (x86)', '')
 
-        for path, subst in self.path_substitutions.iteritems():
+        for path, subst in self.path_substitutions.items():
             parts = filename.split(path)
             if len(parts) >= 2:
                 if self.PRE_PROFILE == '' and subst == '{profile}':
@@ -68,7 +69,7 @@ class Whitelist:
 
                 filename = "%s%s" % (subst, path.join(parts[1:]))
 
-        for old_name, new_name in self.name_substitutions.iteritems():
+        for old_name, new_name in self.name_substitutions.items():
             parts = filename.split(old_name)
             if len(parts) >= 2:
                 filename = "%s%s" % (parts[0], new_name)
@@ -77,7 +78,7 @@ class Whitelist:
 
     def check(self, test, file_name_index):
         errors = {}
-        for row_key in test.iterkeys():
+        for row_key in test.keys():
             filename = self.sanitize_filename(row_key[file_name_index])
 
             if filename in self.listmap:
@@ -94,7 +95,7 @@ class Whitelist:
 
     def checkDuration(self, test, file_name_index, file_duration_index):
         errors = {}
-        for idx, (row_key, row_value) in utils.indexed_items(test.iteritems()):
+        for idx, (row_key, row_value) in utils.indexed_items(test.items()):
             if row_value[file_duration_index] > DEFAULT_DURATION:
                 filename = self.sanitize_filename(row_key[file_name_index])
                 if filename in self.listmap and \
@@ -127,7 +128,7 @@ class Whitelist:
     @staticmethod
     def get_error_strings(errors):
         error_strs = []
-        for filename, data in errors.iteritems():
+        for filename, data in errors.items():
             for datum in data:
                 error_strs.append("File '%s' was accessed and we were not"
                                   " expecting it: %r" % (filename, datum))
@@ -135,8 +136,8 @@ class Whitelist:
 
     def print_errors(self, error_strs):
         for error_msg in error_strs:
-            print("TEST-UNEXPECTED-FAIL | %s | %s" % (self.test_name,
-                                                      error_msg))
+            print(("TEST-UNEXPECTED-FAIL | %s | %s" % (self.test_name,
+                                                      error_msg)))
 
     # Note that we don't store dependent libs in listmap. This makes
     # save_baseline cleaner. Since a baseline whitelist should not include
@@ -153,5 +154,5 @@ class Whitelist:
                     {'ignore': True} for lib in libs}
             return True
         except IOError as e:
-            print("%s: %s" % (e.filename, e.strerror))
+            print(("%s: %s" % (e.filename, e.strerror)))
             return False
diff --git a/testing/talos/talos/xtalos/__init__.py b/testing/talos/talos/xtalos/__init__.py
index 73122f3553..ec0dcb9fca 100644
--- a/testing/talos/talos/xtalos/__init__.py
+++ b/testing/talos/talos/xtalos/__init__.py
@@ -1,5 +1,5 @@
 # xtalos: talos + xperf
 
-from start_xperf import start  # noqa
-from start_xperf import start_from_config  # noqa
-import etlparser  # noqa
+from .start_xperf import start  # noqa
+from .start_xperf import start_from_config  # noqa
+from . import etlparser  # noqa
diff --git a/testing/talos/talos/xtalos/etlparser.py b/testing/talos/talos/xtalos/etlparser.py
index d52c112e18..e9a3c42156 100644
--- a/testing/talos/talos/xtalos/etlparser.py
+++ b/testing/talos/talos/xtalos/etlparser.py
@@ -4,11 +4,12 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import csv
 import re
 import os
 import sys
-import xtalos
+from . import xtalos
 import subprocess
 import json
 import mozfile
@@ -79,7 +80,7 @@ def getIndex(eventType, colName):
 
 
 def readFile(filename):
-    print("etlparser: in readfile: %s" % filename)
+    print(("etlparser: in readfile: %s" % filename))
     data = csv.reader(open(filename, 'rb'), delimiter=',', quotechar='"',
                       skipinitialspace=True)
     data = filterOutHeader(data)
@@ -150,7 +151,7 @@ def etl2csv(xperf_path, etl_filename, debug=False):
                  '%s.kernel' % etl_filename,
                  etl_filename]
     if debug:
-        print("executing '%s'" % subprocess.list2cmdline(xperf_cmd))
+        print(("executing '%s'" % subprocess.list2cmdline(xperf_cmd)))
     subprocess.call(xperf_cmd)
 
     csv_filename = '%s.csv' % etl_filename
@@ -158,7 +159,7 @@ def etl2csv(xperf_path, etl_filename, debug=False):
                  '-i', etl_filename,
                  '-o', csv_filename]
     if debug:
-        print("executing '%s'" % subprocess.list2cmdline(xperf_cmd))
+        print(("executing '%s'" % subprocess.list2cmdline(xperf_cmd)))
     subprocess.call(xperf_cmd)
     return csv_filename
 
@@ -226,7 +227,7 @@ def loadWhitelist(filename):
     if not filename:
         return
     if not os.path.exists(filename):
-        print("Warning: xperf whitelist %s was not found" % filename)
+        print(("Warning: xperf whitelist %s was not found" % filename))
         return
     lines = open(filename).readlines()
     # Expand paths
@@ -276,7 +277,7 @@ def etlparser(xperf_path, etl_filename, processID, approot=None,
     io = {}
     stage = 0
 
-    print("reading etl filename: %s" % etl_filename)
+    print(("reading etl filename: %s" % etl_filename))
     csvname = etl2csv(xperf_path, etl_filename, debug=debug)
     for row in readFile(csvname):
         event = row[EVENTNAME_INDEX]
@@ -297,7 +298,7 @@ def etlparser(xperf_path, etl_filename, processID, approot=None,
         mozfile.remove(csvname)
 
     output = "thread, stage, counter, value\n"
-    for cntr in sorted(io.iterkeys()):
+    for cntr in sorted(io.keys()):
         output += "%s, %s\n" % (", ".join(cntr), str(io[cntr]))
     if outputFile:
         fname = "%s_thread_stats%s" % os.path.splitext(outputFile)
@@ -314,11 +315,10 @@ def etlparser(xperf_path, etl_filename, processID, approot=None,
 
     # Filter out stages, threads, and whitelisted files that we're not
     # interested in
-    filekeys = filter(lambda x: (all_stages or x[2] == stages[0]) and
+    filekeys = [x for x in files.keys() if (all_stages or x[2] == stages[0]) and
                                 (all_threads or x[1].endswith("(main)")) and
                                 (all_stages and x[2] != stages[0] or
-                                 not checkWhitelist(x[0], whitelist)),
-                      files.iterkeys())
+                                 not checkWhitelist(x[0], whitelist))]
 
     # output data
     for row in filekeys:
@@ -447,7 +447,7 @@ def etlparser(xperf_path, etl_filename, processID, approot=None,
         for error in errors:
             # NOTE: the ' :' is intentional, without the space before the :,
             # some parser will translate this
-            print("TEST-UNEXPECTED-FAIL : xperf: %s" % error)
+            print(("TEST-UNEXPECTED-FAIL : xperf: %s" % error))
 
         # We detect if browser_failures.txt exists to exit and turn the job
         # orange
diff --git a/testing/talos/talos/xtalos/parse_xperf.py b/testing/talos/talos/xtalos/parse_xperf.py
index c53425fa33..9dfde5d79d 100644
--- a/testing/talos/talos/xtalos/parse_xperf.py
+++ b/testing/talos/talos/xtalos/parse_xperf.py
@@ -4,17 +4,18 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import sys
-import xtalos
+from . import xtalos
 import subprocess
-import etlparser
+from . import etlparser
 
 
 def stop(xperf_path, debug=False):
     xperf_cmd = [xperf_path, '-stop', '-stop', 'talos_ses']
     if debug:
-        print("executing '%s'" % subprocess.list2cmdline(xperf_cmd))
+        print(("executing '%s'" % subprocess.list2cmdline(xperf_cmd)))
     subprocess.call(xperf_cmd)
 
 
diff --git a/testing/talos/talos/xtalos/start_xperf.py b/testing/talos/talos/xtalos/start_xperf.py
index 06585b4797..2e8503318f 100644
--- a/testing/talos/talos/xtalos/start_xperf.py
+++ b/testing/talos/talos/xtalos/start_xperf.py
@@ -4,9 +4,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import sys
-import xtalos
+from . import xtalos
 import subprocess
 
 
@@ -26,7 +27,7 @@ def start(xperf_path, xperf_providers, xperf_stackwalk, xperf_user_providers,
                  '-f', '%s.user' % etl_filename
                  ]
     if debug:
-        print("executing '%s'" % subprocess.list2cmdline(xperf_cmd))
+        print(("executing '%s'" % subprocess.list2cmdline(xperf_cmd)))
     subprocess.call(xperf_cmd)
 
 
diff --git a/testing/talos/talos/xtalos/xtalos.py b/testing/talos/talos/xtalos/xtalos.py
index df9a9eecc3..1e739ce1d7 100644
--- a/testing/talos/talos/xtalos/xtalos.py
+++ b/testing/talos/talos/xtalos/xtalos.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import argparse
 import json
@@ -120,7 +121,7 @@ class XtalosOptions(argparse.ArgumentParser):
         # ensure xperf path exists
         options.xperf_path = os.path.abspath(options.xperf_path)
         if not os.path.exists(options.xperf_path):
-            print("ERROR: xperf_path '%s' does not exist" % options.xperf_path)
+            print(("ERROR: xperf_path '%s' does not exist" % options.xperf_path))
             return None
 
         return options
diff --git a/testing/talos/talos_from_code.py b/testing/talos/talos_from_code.py
index 3ac2ffd582..fa93afa977 100644
--- a/testing/talos/talos_from_code.py
+++ b/testing/talos/talos_from_code.py
@@ -9,11 +9,12 @@
 # Author(s):     Zambrano Gasparnian, Armen 
 # Target:        Python 2.5
 #
+from __future__ import print_function
 from optparse import OptionParser
 import json
 import re
-import urllib2
-import urlparse
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
+import six.moves.urllib.parse
 import sys
 import os
 
@@ -40,27 +41,27 @@ def main():
         jsonFilename = download_file(options.talos_json_url)
     except Exception as e:
         print("ERROR: We tried to download the talos.json file but something failed.")
-        print("ERROR: %s" % str(e))
+        print(("ERROR: %s" % str(e)))
         sys.exit(1)
 
     # 3) download the necessary files
-    print("INFO: talos.json URL: %s" % options.talos_json_url)
+    print(("INFO: talos.json URL: %s" % options.talos_json_url))
     try:
         key = 'talos.zip'
         entity = get_value(jsonFilename, key)
         if passesRestrictions(options.talos_json_url, entity["url"]):
             # the key is at the same time the filename e.g. talos.zip
-            print("INFO: Downloading %s as %s" %
-                  (entity["url"], os.path.join(entity["path"], key)))
+            print(("INFO: Downloading %s as %s" %
+                  (entity["url"], os.path.join(entity["path"], key))))
             download_file(entity["url"], entity["path"], key)
         else:
-            print("ERROR: You have tried to download a file " +
+            print(("ERROR: You have tried to download a file " +
                   "from: %s " % entity["url"] +
-                  "which is a location different than http://talos-bundles.pvt.build.mozilla.org/")
+                  "which is a location different than http://talos-bundles.pvt.build.mozilla.org/"))
             print("ERROR: This is only allowed for the certain branches.")
             sys.exit(1)
     except Exception as e:
-        print("ERROR: %s" % str(e))
+        print(("ERROR: %s" % str(e)))
         sys.exit(1)
 
 
@@ -88,12 +89,12 @@ def get_filename_from_url(url):
     '''
     This returns the filename of the file we're trying to download
     '''
-    parsed = urlparse.urlsplit(url.rstrip('/'))
+    parsed = six.moves.urllib.parse.urlsplit(url.rstrip('/'))
     if parsed.path != '':
         return parsed.path.rsplit('/', 1)[-1]
     else:
-        print("ERROR: We were trying to download a file from %s " +
-              "but the URL seems to be incorrect.")
+        print(("ERROR: We were trying to download a file from %s " +
+              "but the URL seems to be incorrect."))
         sys.exit(1)
 
 
@@ -101,14 +102,14 @@ def download_file(url, path="", saveAs=None):
     '''
     It downloads a file from URL to the indicated path
     '''
-    req = urllib2.Request(url)
-    f = urllib2.urlopen(req)
+    req = six.moves.urllib.request.Request(url)
+    f = six.moves.urllib.request.urlopen(req)
     if path != "" and not os.path.isdir(path):
         try:
             os.makedirs(path)
-            print("INFO: directory %s created" % path)
+            print(("INFO: directory %s created" % path))
         except Exception as e:
-            print("ERROR: %s" % str(e))
+            print(("ERROR: %s" % str(e)))
             sys.exit(1)
     filename = saveAs if saveAs else get_filename_from_url(url)
     local_file = open(os.path.join(path, filename), 'wb')
diff --git a/testing/talos/tests/test_browser_output.py b/testing/talos/tests/test_browser_output.py
index 7b95733c01..ee837bb059 100644
--- a/testing/talos/tests/test_browser_output.py
+++ b/testing/talos/tests/test_browser_output.py
@@ -52,7 +52,7 @@ class TestBrowserOutput(unittest.TestCase):
         pageloader_results = PageloaderResults(raw_report)
         self.assertEqual(len(pageloader_results.results), 12)
         indices = [i['index'] for i in pageloader_results.results]
-        self.assertEqual(indices, range(12))
+        self.assertEqual(indices, list(range(12)))
 
         # test hixie-001.xml just as a spot-check
         hixie_001 = pageloader_results.results[5]
diff --git a/testing/talos/tests/test_filter.py b/testing/talos/tests/test_filter.py
index b4e2d39cf9..cbe9e5c7f1 100755
--- a/testing/talos/tests/test_filter.py
+++ b/testing/talos/tests/test_filter.py
@@ -12,7 +12,7 @@ import talos.filter
 
 class TestFilter(unittest.TestCase):
 
-    data = range(30)  # test data
+    data = list(range(30))  # test data
 
     def test_ignore(self):
         """test the ignore filter"""
diff --git a/testing/talos/tests/test_results.py b/testing/talos/tests/test_results.py
index 015da8ed26..cb5985435b 100755
--- a/testing/talos/tests/test_results.py
+++ b/testing/talos/tests/test_results.py
@@ -44,7 +44,7 @@ class TestPageloaderResults(unittest.TestCase):
 
         # test the indices
         indices = [i['index'] for i in results.results]
-        self.assertEqual(indices, range(12))
+        self.assertEqual(indices, list(range(12)))
 
         # test some pages
         pages = [i['page'] for i in results.results]
diff --git a/testing/tools/autotry/autotry.py b/testing/tools/autotry/autotry.py
index 7b0350b610..5c359c09c1 100644
--- a/testing/tools/autotry/autotry.py
+++ b/testing/tools/autotry/autotry.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import argparse
 import itertools
 import os
@@ -12,7 +13,8 @@ import which
 
 from collections import defaultdict
 
-import ConfigParser
+import six.moves.configparser
+import six
 
 
 def arg_parser():
@@ -96,7 +98,7 @@ class TryArgumentParser(object):
 
     def consume(self):
         try:
-            self.token = self.tokens.next()
+            self.token = next(self.tokens)
         except StopIteration:
             self.token = (self.EOF, None)
 
@@ -277,14 +279,14 @@ class AutoTry(object):
         return os.path.join(self.mach_context.state_dir, "autotry.ini")
 
     def load_config(self, name):
-        config = ConfigParser.RawConfigParser()
+        config = six.moves.configparser.RawConfigParser()
         success = config.read([self.config_path])
         if not success:
             return None
 
         try:
             data = config.get("try", name)
-        except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
+        except (six.moves.configparser.NoSectionError, six.moves.configparser.NoOptionError):
             return None
 
         kwargs = vars(arg_parser().parse_args(self.split_try_string(data)))
@@ -292,21 +294,21 @@ class AutoTry(object):
         return kwargs
 
     def list_presets(self):
-        config = ConfigParser.RawConfigParser()
+        config = six.moves.configparser.RawConfigParser()
         success = config.read([self.config_path])
 
         data = []
         if success:
             try:
                 data = config.items("try")
-            except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
+            except (six.moves.configparser.NoSectionError, six.moves.configparser.NoOptionError):
                 pass
 
         if not data:
             print("No presets found")
 
         for name, try_string in data:
-            print("%s: %s" % (name, try_string))
+            print(("%s: %s" % (name, try_string)))
 
     def split_try_string(self, data):
         return re.findall(r'(?:\[.*?\]|\S)+', data)
@@ -315,7 +317,7 @@ class AutoTry(object):
         assert data.startswith("try: ")
         data = data[len("try: "):]
 
-        parser = ConfigParser.RawConfigParser()
+        parser = six.moves.configparser.RawConfigParser()
         parser.read([self.config_path])
 
         if not parser.has_section("try"):
@@ -388,7 +390,7 @@ class AutoTry(object):
 
         suites = tests if not intersection else {}
         paths = set()
-        for flavor, flavor_tests in paths_by_flavor.iteritems():
+        for flavor, flavor_tests in paths_by_flavor.items():
             suite = self.flavor_suites[flavor]
             if suite not in suites and (not intersection or suite in tests):
                 for job_name in self.flavor_jobs[flavor]:
@@ -423,7 +425,7 @@ class AutoTry(object):
             parts.append("--try-test-paths %s" % " ".join(sorted(paths)))
 
         args_by_dest = {v['dest']: k for k, v in AutoTry.pass_through_arguments.items()}
-        for dest, value in extras.iteritems():
+        for dest, value in extras.items():
             assert dest in args_by_dest
             arg = args_by_dest[dest]
             action = AutoTry.pass_through_arguments[arg]['action']
@@ -438,7 +440,7 @@ class AutoTry(object):
                 parts.append(arg)
 
         try_syntax = " ".join(parts)
-        if extras.get('artifact') and 'all' in suites.keys():
+        if extras.get('artifact') and 'all' in list(suites.keys()):
             message = ('You asked for |-u all| with |--artifact| but compiled-code tests ({tests})'
                        ' can\'t run against an artifact build. Try listing the suites you want'
                        ' instead. For example, this syntax covers most suites:\n{try_syntax}')
@@ -457,8 +459,8 @@ class AutoTry(object):
         args = ['git'] + list(args)
         ret = subprocess.call(args)
         if ret:
-            print('ERROR git command %s returned %s' %
-                  (args, ret))
+            print(('ERROR git command %s returned %s' %
+                  (args, ret)))
             sys.exit(1)
 
     def _git_push_to_try(self, msg):
@@ -485,8 +487,8 @@ class AutoTry(object):
             return subprocess.check_output(args).strip('\0').split('\0')
         except subprocess.CalledProcessError as e:
             print('Failed while determining files changed on this branch')
-            print('Failed whle running: %s' % args)
-            print(e.output)
+            print(('Failed whle running: %s' % args))
+            print((e.output))
             sys.exit(1)
 
     def _hg_find_changed_files(self):
@@ -501,8 +503,8 @@ class AutoTry(object):
         except subprocess.CalledProcessError as e:
             print('Failed while finding files changed since the last '
                   'public ancestor')
-            print('Failed whle running: %s' % hg_args)
-            print(e.output)
+            print(('Failed whle running: %s' % hg_args))
+            print((e.output))
             sys.exit(1)
 
     def find_changed_files(self):
@@ -521,7 +523,7 @@ class AutoTry(object):
                 hg_args = ['hg', 'push-to-try', '-m', msg]
                 subprocess.check_call(hg_args, stderr=subprocess.STDOUT)
             except subprocess.CalledProcessError as e:
-                print('ERROR hg command %s returned %s' % (hg_args, e.returncode))
+                print(('ERROR hg command %s returned %s' % (hg_args, e.returncode)))
                 print('\nmach failed to push to try. There may be a problem '
                       'with your ssh key, or another issue with your mercurial '
                       'installation.')
@@ -560,8 +562,8 @@ class AutoTry(object):
         changed_files = self.find_changed_files()
         if changed_files:
             if verbose:
-                print("Pushing tests based on modifications to the "
-                      "following files:\n\t%s" % "\n\t".join(changed_files))
+                print(("Pushing tests based on modifications to the "
+                      "following files:\n\t%s" % "\n\t".join(changed_files)))
 
             from mozbuild.frontend.reader import (
                 BuildReader,
@@ -578,9 +580,9 @@ class AutoTry(object):
 
             if verbose:
                 if paths:
-                    print("Pushing tests based on the following patterns:\n\t%s" %
-                          "\n\t".join(paths))
+                    print(("Pushing tests based on the following patterns:\n\t%s" %
+                          "\n\t".join(paths)))
                 if tags:
-                    print("Pushing tests based on the following tags:\n\t%s" %
-                          "\n\t".join(tags))
+                    print(("Pushing tests based on the following tags:\n\t%s" %
+                          "\n\t".join(tags)))
         return paths, tags
diff --git a/testing/tools/iceserver/iceserver.py b/testing/tools/iceserver/iceserver.py
index 85d0f3ee54..cd5134c971 100644
--- a/testing/tools/iceserver/iceserver.py
+++ b/testing/tools/iceserver/iceserver.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import ipaddr
 import socket
 import hmac
@@ -18,6 +19,7 @@ from string import Template
 from twisted.internet import reactor, protocol
 from twisted.internet.task import LoopingCall
 from twisted.internet.address import IPv4Address
+from functools import reduce
 
 MAGIC_COOKIE = 0x2112A442
 
@@ -321,7 +323,7 @@ class StunMessage(object):
         digest_buf = self.build(MESSAGE_INTEGRITY)
         # Trim off the MESSAGE-INTEGRITY attr
         digest_buf = digest_buf[:len(digest_buf) - 24]
-        password = passlib.utils.saslprep(unicode(password))
+        password = passlib.utils.saslprep(str(password))
         key_string = "{}:{}:{}".format(username, realm, password)
         md5 = hashlib.md5()
         md5.update(key_string)
@@ -367,10 +369,11 @@ class Allocation(protocol.DatagramProtocol):
         self.expiry = time.time()
         self.port = reactor.listenUDP(0, self, interface=v4_address)
 
-    def datagramReceived(self, data, (host, port)):
+    def datagramReceived(self, data, xxx_todo_changeme):
+        (host, port) = xxx_todo_changeme
         if not host in self.permissions:
-            print("Dropping packet from {}:{}, no permission on allocation {}"
-                  .format(host, port, self.transport.getHost()))
+            print(("Dropping packet from {}:{}, no permission on allocation {}"
+                  .format(host, port, self.transport.getHost())))
             return
 
         data_indication = StunMessage()
@@ -421,13 +424,13 @@ class StunHandler(object):
             if stun_message.method == SEND:
                 self.handle_send_indication(stun_message)
             else:
-                print("Dropping unknown indication method: {}"
-                      .format(stun_message.method))
+                print(("Dropping unknown indication method: {}"
+                      .format(stun_message.method)))
             return None
 
         if stun_message.msg_class != REQUEST:
-            print("Dropping STUN response, method: {}"
-                  .format(stun_message.method))
+            print(("Dropping STUN response, method: {}"
+                  .format(stun_message.method)))
             return None
 
         if stun_message.method == BINDING:
@@ -559,8 +562,8 @@ class StunHandler(object):
         try:
             allocation = allocations[self.get_allocation_tuple()]
         except KeyError:
-            print("Dropping send indication; no allocation for tuple {}"
-                  .format(self.get_allocation_tuple()))
+            print(("Dropping send indication; no allocation for tuple {}"
+                  .format(self.get_allocation_tuple())))
             return
 
         peer_address = indication.get_xor_address(XOR_PEER_ADDRESS)
@@ -578,8 +581,8 @@ class StunHandler(object):
             return
 
         if not peer_address.host in allocation.permissions:
-            print("Dropping send indication, no permission for {} on tuple {}"
-                  .format(peer_address.host, self.get_allocation_tuple()))
+            print(("Dropping send indication, no permission for {} on tuple {}"
+                  .format(peer_address.host, self.get_allocation_tuple())))
             return
 
         allocation.transport.write(data_attr.data,
@@ -594,7 +597,7 @@ class StunHandler(object):
 
     def make_error_response(self, request, code, reason=None):
         if reason:
-            print("{}: rejecting with {}".format(reason, code))
+            print(("{}: rejecting with {}".format(reason, code)))
         response = copy.deepcopy(request)
         response.attributes = []
         response.add_error_code(code, reason)
@@ -676,12 +679,12 @@ class TcpStunHandler(protocol.Protocol):
         self.stun_handler.data_received(data, self.address)
 
     def connectionLost(self, reason):
-        print("Lost connection from {}".format(self.address))
+        print(("Lost connection from {}".format(self.address)))
         # Destroy allocations that this connection made
         for key, allocation in allocations.items():
             if allocation.other_transport_handler == self:
-                print("Closing allocation due to dropped connection: {}"
-                      .format(key))
+                print(("Closing allocation due to dropped connection: {}"
+                      .format(key)))
                 del allocations[key]
                 allocation.close()
 
@@ -713,7 +716,7 @@ def prune_allocations():
     now = time.time()
     for key, allocation in allocations.items():
         if allocation.expiry < now:
-            print("Allocation expired: {}".format(key))
+            print(("Allocation expired: {}".format(key)))
             del allocations[key]
             allocation.close()
 
@@ -789,7 +792,7 @@ if __name__ == "__main__":
         lines = f.readlines();
         lines.pop(0); # Remove BEGIN CERTIFICATE
         lines.pop(); # Remove END CERTIFICATE
-        lines = map(string.strip, lines);
+        lines = list(map(string.strip, lines));
         certbase64 = string.join(lines, '');
 
         turns_url = ', "turns:' + hostname + '"'
@@ -810,11 +813,11 @@ if __name__ == "__main__":
 $cert_prop}]' # Hack to make it easier to override cert checks
 )
 
-    print(template.substitute(user=turn_user,
+    print((template.substitute(user=turn_user,
                               pwd=turn_pass,
                               hostname=hostname,
                               turns_url=turns_url,
-                              cert_prop=cert_prop))
+                              cert_prop=cert_prop)))
 
     reactor.run()
 
diff --git a/testing/tools/proxyserver/proxyserver.py b/testing/tools/proxyserver/proxyserver.py
index d7b2ef1610..a210fcff9b 100644
--- a/testing/tools/proxyserver/proxyserver.py
+++ b/testing/tools/proxyserver/proxyserver.py
@@ -45,6 +45,7 @@ TODO:
   items from the database and such.
 """
 
+from __future__ import print_function
 __version__ = "0.1"
 
 import os
@@ -54,13 +55,13 @@ import threading
 import shelve
 from optparse import OptionParser, OptionValueError
 
-import SocketServer
-import BaseHTTPServer
+import six.moves.socketserver
+import six.moves.BaseHTTPServer
 import socket
-import httplib
-from urlparse import urlsplit, urlunsplit
+import six.moves.http_client
+from urllib.parse import urlsplit, urlunsplit
 
-class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+class HTTPRequestHandler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler):
   server_version = "TalosProxy/" + __version__
   protocol_version = "HTTP/1.1"
 
@@ -69,9 +70,9 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
     if content:
       try:
         self.wfile.write(content)
-      except socket.error, e:
+      except socket.error as e:
         if options.verbose:
-          print "Got socket error %s" % e
+          print("Got socket error %s" % e)
     #self.close_connection = 1
   def do_HEAD(self):
     self.send_head()
@@ -108,8 +109,8 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
         return None
       else:
         if options.verbose:
-          print "Object %s was not in the cache" % self.path
-        conn = httplib.HTTPConnection(o.netloc)
+          print("Object %s was not in the cache" % self.path)
+        conn = six.moves.http_client.HTTPConnection(o.netloc)
         conn.request("GET", reqstring, headers=headers)
         res = conn.getresponse()
 
@@ -133,18 +134,18 @@ class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
       if "Content-Length" not in headers:
         self.send_header("Content-Length", str(len(content)))
       self.end_headers()
-    except socket.error, e:
+    except socket.error as e:
       if options.verbose:
-        print "Got socket error %s" % e
+        print("Got socket error %s" % e)
       return None
     return content
   def log_message(self, format, *args):
     if options.verbose:
-      BaseHTTPServer.BaseHTTPRequestHandler.log_message(self, format, *args)
+      six.moves.BaseHTTPServer.BaseHTTPRequestHandler.log_message(self, format, *args)
 
-class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
+class HTTPServer(six.moves.socketserver.ThreadingMixIn, six.moves.BaseHTTPServer.HTTPServer):
   def __init__(self, address, handler):
-    BaseHTTPServer.HTTPServer.__init__(self, address, handler)
+    six.moves.BaseHTTPServer.HTTPServer.__init__(self, address, handler)
 
 class Cache(object):
   """Multithreaded cache uses the shelve module to store pages"""
@@ -176,7 +177,7 @@ class Cache(object):
     self.sem.acquire()
     self.semlock.release()
     try:
-      if not self.db.has_key(key):
+      if key not in self.db:
         return None
       # returns status, headers, content
       return self.db[key]
@@ -264,6 +265,6 @@ if __name__ == '__main__':
     while 1: time.sleep(1)
   except KeyboardInterrupt:
     if options.verbose:
-      print "Quittin' time..."
+      print("Quittin' time...")
 
 __all__ = ['run_proxy', 'configure_proxy']
diff --git a/testing/tools/websocketprocessbridge/websocketprocessbridge.py b/testing/tools/websocketprocessbridge/websocketprocessbridge.py
index 02418d0e67..3df0ec2d26 100644
--- a/testing/tools/websocketprocessbridge/websocketprocessbridge.py
+++ b/testing/tools/websocketprocessbridge/websocketprocessbridge.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 from twisted.internet import protocol, reactor
 from twisted.internet.task import LoopingCall
 import txws
@@ -99,7 +100,7 @@ if __name__ == "__main__":
 
     bridgeFactory = ProcessSocketBridgeFactory()
     reactor.listenTCP(int(args.port), txws.WebSocketFactory(bridgeFactory))
-    print("websocket/process bridge listening on port %s" % args.port)
+    print(("websocket/process bridge listening on port %s" % args.port))
     reactor.run()
 
 
diff --git a/testing/tps/create_venv.py b/testing/tps/create_venv.py
index 3d5417f8af..82139b9d4c 100755
--- a/testing/tps/create_venv.py
+++ b/testing/tps/create_venv.py
@@ -9,13 +9,15 @@ It's probably best to specify a path NOT inside the repo, otherwise
 all the virtualenv files will show up in e.g. hg status.
 """
 
+from __future__ import print_function
 import optparse
 import os
 import shutil
 import subprocess
 import sys
-import urllib2
+import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 import zipfile
+import six
 
 
 here = os.path.dirname(os.path.abspath(__file__))
@@ -53,7 +55,7 @@ else:
 
 def download(url, target):
     """Downloads the specified url to the given target."""
-    response = urllib2.urlopen(url)
+    response = six.moves.urllib.request.urlopen(url)
     with open(target, 'wb') as f:
         f.write(response.read())
 
@@ -64,7 +66,7 @@ def setup_virtualenv(target, python_bin=None):
     script_path = os.path.join(here, 'virtualenv-%s' % VERSION_VIRTUALENV,
                                'virtualenv.py')
 
-    print 'Downloading virtualenv %s' % VERSION_VIRTUALENV
+    print('Downloading virtualenv %s' % VERSION_VIRTUALENV)
     zip_path = download(URL_VIRTUALENV + VERSION_VIRTUALENV,
                         os.path.join(here, 'virtualenv.zip'))
 
@@ -72,7 +74,7 @@ def setup_virtualenv(target, python_bin=None):
         with zipfile.ZipFile(zip_path, 'r') as f:
             f.extractall(here)
 
-        print 'Creating new virtual environment'
+        print('Creating new virtual environment')
         cmd_args = [sys.executable, script_path, target]
 
         if python_bin:
@@ -93,7 +95,7 @@ def update_configfile(source, target, replacements):
 
     with open(source) as config:
         for line in config:
-            for source_string, target_string in replacements.iteritems():
+            for source_string, target_string in replacements.items():
                 if target_string:
                     line = line.replace(source_string, target_string)
             lines.append(line)
@@ -153,7 +155,7 @@ def main():
 
     # Activate tps environment
     tps_env = os.path.join(target, activate_env)
-    execfile(tps_env, dict(__file__=tps_env))
+    exec(compile(open(tps_env, "rb").read(), tps_env, 'exec'), dict(__file__=tps_env))
 
     # Install TPS in environment
     subprocess.check_call([os.path.join(target, python_env),
@@ -182,13 +184,13 @@ def main():
                       '__SYNC_ACCOUNT_PASSPHRASE__': options.sync_passphrase})
 
     if not (options.username and options.password):
-        print '\nFirefox Account credentials not specified.'
+        print('\nFirefox Account credentials not specified.')
     if not (options.sync_username and options.sync_password and options.passphrase):
-        print '\nFirefox Sync account credentials not specified.'
+        print('\nFirefox Sync account credentials not specified.')
 
     # Print the user instructions
-    print usage_message.format(TARGET=target,
-                               BIN_NAME=bin_name)
+    print(usage_message.format(TARGET=target,
+                               BIN_NAME=bin_name))
 
 if __name__ == "__main__":
     main()
diff --git a/testing/tps/tps/cli.py b/testing/tps/tps/cli.py
index 63e8db0d40..81bdea4791 100644
--- a/testing/tps/tps/cli.py
+++ b/testing/tps/tps/cli.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import json
 import optparse
 import os
@@ -93,7 +94,7 @@ def main():
 
     rlock = RLock()
 
-    print 'using result file', options.resultfile
+    print('using result file', options.resultfile)
 
     extensionDir = config.get('extensiondir')
     if not extensionDir or extensionDir == '__EXTENSIONDIR__':
diff --git a/testing/tps/tps/firefoxrunner.py b/testing/tps/tps/firefoxrunner.py
index 3b7c143d89..7bf6ed30eb 100644
--- a/testing/tps/tps/firefoxrunner.py
+++ b/testing/tps/tps/firefoxrunner.py
@@ -3,6 +3,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
+from __future__ import print_function
 import copy
 import httplib2
 import os
@@ -53,11 +54,11 @@ class TPSFirefoxRunner(object):
             os.remove(pathToBuild)
 
         # download the build
-        print 'downloading build'
+        print('downloading build')
         self.download_url(self.url, pathToBuild)
 
         # install the build
-        print 'installing %s' % pathToBuild
+        print('installing %s' % pathToBuild)
         mozfile.remove(self.installdir, True)
         binary = mozinstall.install(src=pathToBuild, dest=self.installdir)
 
diff --git a/testing/tps/tps/testrunner.py b/testing/tps/tps/testrunner.py
index 8e5aee6c83..fe0b367196 100644
--- a/testing/tps/tps/testrunner.py
+++ b/testing/tps/tps/testrunner.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import json
 import os
 import platform
@@ -164,7 +165,7 @@ class TPSTestRunner(object):
         f.write(msg)
         f.close()
         if printToConsole:
-            print msg
+            print(msg)
 
     def writeToResultFile(self, postdata, body=None,
                           sendTo=['crossweave@mozilla.com']):
@@ -347,7 +348,7 @@ class TPSTestRunner(object):
 
         self.log(logstr, True)
         for phase in phaselist:
-            print "\t%s: %s" % (phase.phase, phase.status)
+            print("\t%s: %s" % (phase.phase, phase.status))
 
         return resultdata
 
@@ -428,9 +429,9 @@ class TPSTestRunner(object):
             self.rlock.release()
 
         # dump out a summary of test results
-        print 'Test Summary\n'
+        print('Test Summary\n')
         for test in self.postdata.get('tests', {}):
-            print '%s | %s | %s' % (test['state'], test['name'], test['message'])
+            print('%s | %s | %s' % (test['state'], test['name'], test['message']))
 
     def run_test_group(self):
         self.results = []
@@ -476,7 +477,7 @@ class TPSTestRunner(object):
             else:
                 self.numfailed += 1
                 if self.stop_on_error:
-                    print '\nTest failed with --stop-on-error specified; not running any more tests.\n'
+                    print('\nTest failed with --stop-on-error specified; not running any more tests.\n')
                     break
 
         self.mozhttpd.stop()
diff --git a/testing/xpcshell/mach_commands.py b/testing/xpcshell/mach_commands.py
index d821ff46fb..dc6033cdd5 100644
--- a/testing/xpcshell/mach_commands.py
+++ b/testing/xpcshell/mach_commands.py
@@ -29,7 +29,7 @@ from xpcshellcommandline import parser_desktop, parser_remote
 here = os.path.abspath(os.path.dirname(__file__))
 
 if sys.version_info[0] < 3:
-    unicode_type = unicode
+    unicode_type = str
 else:
     unicode_type = str
 
@@ -124,7 +124,7 @@ class XPCShellRunner(MozbuildObject):
         # Python through 2.7.2 has issues with unicode in some of the
         # arguments. Work around that.
         filtered_args = {}
-        for k, v in kwargs.iteritems():
+        for k, v in kwargs.items():
             if isinstance(v, unicode_type):
                 v = v.encode('utf-8')
 
diff --git a/testing/xpcshell/mach_test_package_commands.py b/testing/xpcshell/mach_test_package_commands.py
index fc7d273859..c8a8169026 100644
--- a/testing/xpcshell/mach_test_package_commands.py
+++ b/testing/xpcshell/mach_test_package_commands.py
@@ -44,7 +44,7 @@ def run_xpcshell(context, **kwargs):
     if args.testPaths:
         test_root = os.path.join(context.package_root, 'xpcshell', 'tests')
         normalize = partial(context.normalize_test_path, test_root)
-        args.testPaths = map(normalize, args.testPaths)
+        args.testPaths = list(map(normalize, args.testPaths))
 
     import runxpcshelltests
     xpcshell = runxpcshelltests.XPCShellTests(log=log)
diff --git a/testing/xpcshell/remotexpcshelltests.py b/testing/xpcshell/remotexpcshelltests.py
index c5124880f8..91f7dd1d6a 100644
--- a/testing/xpcshell/remotexpcshelltests.py
+++ b/testing/xpcshell/remotexpcshelltests.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import posixpath
 import sys, os
 import subprocess
@@ -169,7 +170,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
             # The minidumps directory is automatically created when Fennec
             # (first) starts, so its lack of presence is a hint that
             # something went wrong.
-            print "Automation Error: No crash directory (%s) found on remote device" % self.remoteMinidumpDir
+            print("Automation Error: No crash directory (%s) found on remote device" % self.remoteMinidumpDir)
             # Whilst no crash was found, the run should still display as a failure
             return True
         with mozfile.TemporaryDirectory() as dumpDir:
@@ -276,7 +277,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
         elif os.path.isdir(os.path.join(here, 'tests')):
             self.xpcDir = os.path.join(here, 'tests')
         else:
-            print >> sys.stderr, "Couldn't find local xpcshell test directory"
+            print("Couldn't find local xpcshell test directory", file=sys.stderr)
             sys.exit(1)
 
         if options.localAPK:
@@ -321,7 +322,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
         localWrapper = tempfile.mktemp()
         f = open(localWrapper, "w")
         f.write("#!/system/bin/sh\n")
-        for envkey, envval in self.env.iteritems():
+        for envkey, envval in self.env.items():
             f.write("export %s=%s\n" % (envkey, envval))
         f.writelines([
             "cd $1\n",
@@ -376,7 +377,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
                 if packageName:
                     self.appRoot = self.device.getAppRoot(packageName.strip())
             except Exception as detail:
-                print "unable to determine app root: " + str(detail)
+                print("unable to determine app root: " + str(detail))
                 pass
         return None
 
@@ -418,11 +419,11 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
         for fname in binaries:
             local = os.path.join(self.localBin, fname)
             if os.path.isfile(local):
-                print >> sys.stderr, "Pushing %s.." % fname
+                print("Pushing %s.." % fname, file=sys.stderr)
                 remoteFile = remoteJoin(self.remoteBinDir, fname)
                 self.device.pushFile(local, remoteFile)
             else:
-                print >> sys.stderr, "*** Expected binary %s not found in %s!" % (fname, self.localBin)
+                print("*** Expected binary %s not found in %s!" % (fname, self.localBin), file=sys.stderr)
 
         local = os.path.join(self.localBin, "components/httpd.js")
         remoteFile = remoteJoin(self.remoteComponentsDir, "httpd.js")
@@ -449,7 +450,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
                 dir = tempfile.mkdtemp()
                 for info in self.localAPKContents.infolist():
                     if info.filename.endswith(".so"):
-                        print >> sys.stderr, "Pushing %s.." % info.filename
+                        print("Pushing %s.." % info.filename, file=sys.stderr)
                         remoteFile = remoteJoin(self.remoteBinDir, os.path.basename(info.filename))
                         self.localAPKContents.extract(info, dir)
                         localFile = os.path.join(dir, info.filename)
@@ -468,9 +469,9 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
 
         for file in os.listdir(self.localLib):
             if (file.endswith(".so")):
-                print >> sys.stderr, "Pushing %s.." % file
+                print("Pushing %s.." % file, file=sys.stderr)
                 if 'libxul' in file:
-                    print >> sys.stderr, "This is a big file, it could take a while."
+                    print("This is a big file, it could take a while.", file=sys.stderr)
                 localFile = os.path.join(self.localLib, file)
                 remoteFile = remoteJoin(self.remoteBinDir, file)
                 self.device.pushFile(localFile, remoteFile)
@@ -482,7 +483,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
             for root, dirs, files in os.walk(localArmLib):
                 for file in files:
                     if (file.endswith(".so")):
-                        print >> sys.stderr, "Pushing %s.." % file
+                        print("Pushing %s.." % file, file=sys.stderr)
                         localFile = os.path.join(root, file)
                         remoteFile = remoteJoin(self.remoteBinDir, file)
                         self.device.pushFile(localFile, remoteFile)
@@ -495,7 +496,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
             self.device.pushDir(self.testingModulesDir, self.remoteModulesDir)
 
     def setupTestDir(self):
-        print 'pushing %s' % self.xpcDir
+        print('pushing %s' % self.xpcDir)
         try:
             # The tests directory can be quite large: 5000 files and growing!
             # Sometimes - like on a low-end aws instance running an emulator - the push
@@ -560,7 +561,7 @@ class PathMapping:
 
 def main():
     if sys.version_info < (2,7):
-        print >>sys.stderr, "Error: You must use python version 2.7 or newer but less than 3.0"
+        print("Error: You must use python version 2.7 or newer but less than 3.0", file=sys.stderr)
         sys.exit(1)
 
     parser = parser_remote()
@@ -570,10 +571,10 @@ def main():
             if (file.endswith(".apk") and file.startswith("fennec")):
                 options.localAPK = os.path.join(options.objdir, "dist")
                 options.localAPK = os.path.join(options.localAPK, file)
-                print >>sys.stderr, "using APK: " + options.localAPK
+                print("using APK: " + options.localAPK, file=sys.stderr)
                 break
         else:
-            print >>sys.stderr, "Error: please specify an APK"
+            print("Error: please specify an APK", file=sys.stderr)
             sys.exit(1)
 
     options = verifyRemoteOptions(parser, options)
@@ -588,12 +589,12 @@ def main():
             dm = mozdevice.DroidADB(packageName=None, deviceRoot=options.remoteTestRoot)
     else:
         if not options.deviceIP:
-            print "Error: you must provide a device IP to connect to via the --device option"
+            print("Error: you must provide a device IP to connect to via the --device option")
             sys.exit(1)
         dm = mozdevice.DroidSUT(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot)
 
     if options.interactive and not options.testPath:
-        print >>sys.stderr, "Error: You must specify a test filename in interactive mode!"
+        print("Error: You must specify a test filename in interactive mode!", file=sys.stderr)
         sys.exit(1)
 
     if options.xpcshell is None:
diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py
index 34af6639fb..97eec4f836 100755
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import copy
 import importlib
 import json
@@ -24,7 +25,31 @@ import traceback
 
 from collections import deque, namedtuple
 from distutils import dir_util
-from distutils.version import LooseVersion
+try:
+    from distutils.version import LooseVersion
+except ImportError:
+    import re as _re
+    class LooseVersion:
+        def __init__(self, vstring):
+            self.vstring = vstring
+            self.version = [int(x) if x.isdigit() else x for x in _re.split(r'[.\-]', vstring)]
+        def __str__(self): return self.vstring
+        def __repr__(self): return "LooseVersion ('%s')" % str(self)
+        def _cmp(self, other):
+            if not isinstance(other, LooseVersion): other = LooseVersion(other)
+            a, b = self.version, other.version
+            for i in range(max(len(a), len(b))):
+                va = a[i] if i < len(a) else 0
+                vb = b[i] if i < len(b) else 0
+                if type(va) != type(vb): va, vb = str(va), str(vb)
+                if va < vb: return -1
+                if va > vb: return 1
+            return 0
+        def __eq__(self, other): return self._cmp(other) == 0
+        def __lt__(self, other): return self._cmp(other) < 0
+        def __le__(self, other): return self._cmp(other) <= 0
+        def __gt__(self, other): return self._cmp(other) > 0
+        def __ge__(self, other): return self._cmp(other) >= 0
 from multiprocessing import cpu_count
 from argparse import ArgumentParser
 from subprocess import Popen, PIPE, STDOUT
@@ -91,9 +116,9 @@ def cleanup_encoding(s):
        points, etc.  If it is a byte string, it is assumed to be
        UTF-8, but it may not be *correct* UTF-8.  Return a
        sanitized unicode object."""
-    if not isinstance(s, basestring):
-        return unicode(s)
-    if not isinstance(s, unicode):
+    if not isinstance(s, str):
+        return str(s)
+    if not isinstance(s, str):
         s = s.decode('utf-8', 'replace')
     # Replace all C0 and C1 control characters with \xNN escapes.
     return _cleanup_encoding_re.sub(_cleanup_encoding_repl, s)
@@ -267,8 +292,8 @@ class XPCShellTestThread(Thread):
         self.log.info("%s | current directory: %r" % (name, testdir))
         # Show only those environment variables that are changed from
         # the ambient environment.
-        changedEnv = (set("%s=%s" % i for i in self.env.iteritems())
-                      - set("%s=%s" % i for i in os.environ.iteritems()))
+        changedEnv = (set("%s=%s" % i for i in self.env.items())
+                      - set("%s=%s" % i for i in os.environ.items()))
         self.log.info("%s | environment: %s" % (name, list(changedEnv)))
 
     def killTimeout(self, proc):
@@ -514,7 +539,7 @@ class XPCShellTestThread(Thread):
     def log_line(self, line):
         """Log a line of output (either a parser json object or text output from
         the test process"""
-        if isinstance(line, basestring):
+        if isinstance(line, str):
             line = self.fix_text_output(line).rstrip('\r\n')
             self.log.process_output(self.proc_ident,
                                     line,
@@ -822,8 +847,8 @@ class XPCShellTests(object):
         if os.path.exists(ini_path):
             return TestManifest([ini_path], strict=True)
         else:
-            print >> sys.stderr, ("Failed to find manifest at %s; use --manifest "
-                                  "to set path explicitly." % (ini_path,))
+            print(("Failed to find manifest at %s; use --manifest "
+                                  "to set path explicitly." % (ini_path,)), file=sys.stderr)
             sys.exit(1)
 
     def buildTestList(self, test_tags=None, test_paths=None):
@@ -1002,7 +1027,7 @@ class XPCShellTests(object):
                 # node did not support ALPN until this version.
                 if version >= LooseVersion("5.0.0"):
                     nodeBin = localPath
-            except (subprocess.CalledProcessError, OSError), e:
+            except (subprocess.CalledProcessError, OSError) as e:
                 self.log.error('Could not retrieve node version: %s' % str(e))
 
         if os.getenv('MOZ_ASSUME_NODE_RUNNING', None):
@@ -1030,7 +1055,7 @@ class XPCShellTests(object):
                             searchObj = re.search( r'HTTP2 server listening on port (.*)', msg, 0)
                             if searchObj:
                               self.env["MOZHTTP2_PORT"] = searchObj.group(1)
-                    except OSError, e:
+                    except OSError as e:
                         # This occurs if the subprocess couldn't be started
                         self.log.error('Could not run %s server: %s' % (name, str(e)))
 
@@ -1043,7 +1068,7 @@ class XPCShellTests(object):
         """
           Shut down our node process, if it exists
         """
-        for name, proc in self.nodeProc.iteritems():
+        for name, proc in self.nodeProc.items():
             self.log.info('Node %s server shutting down ...' % name)
             if proc.poll() is not None:
                 self.log.info('Node server %s already dead %s' % (name, proc.poll()))
@@ -1150,7 +1175,7 @@ class XPCShellTests(object):
                 os.remove(failure_manifest)
                 manifest = rerun_manifest
             else:
-                print >> sys.stderr, "No failures were found to re-run."
+                print("No failures were found to re-run.", file=sys.stderr)
                 sys.exit(1)
 
         if testingModulesDir:
@@ -1220,7 +1245,7 @@ class XPCShellTests(object):
         # All of the keys in question should be ASCII.
         fixedInfo = {}
         for k, v in self.mozInfo.items():
-            if isinstance(k, unicode):
+            if isinstance(k, str):
                 k = k.encode('ascii')
             fixedInfo[k] = v
         self.mozInfo = fixedInfo
@@ -1483,12 +1508,12 @@ def main():
     log = commandline.setup_logging("XPCShell", options, {"tbpl": sys.stdout})
 
     if options.xpcshell is None:
-        print >> sys.stderr, """Must provide path to xpcshell using --xpcshell"""
+        print("""Must provide path to xpcshell using --xpcshell""", file=sys.stderr)
 
     xpcsh = XPCShellTests(log)
 
     if options.interactive and not options.testPath:
-        print >>sys.stderr, "Error: You must specify a test filename in interactive mode!"
+        print("Error: You must specify a test filename in interactive mode!", file=sys.stderr)
         sys.exit(1)
 
     if not xpcsh.runTests(**vars(options)):
diff --git a/testing/xpcshell/selftest.py b/testing/xpcshell/selftest.py
index 071ab5eda6..711302188b 100755
--- a/testing/xpcshell/selftest.py
+++ b/testing/xpcshell/selftest.py
@@ -447,7 +447,7 @@ class XPCShellTestsTests(unittest.TestCase):
         """
         testlines = []
         for t in tests:
-            testlines.append("[%s]" % (t if isinstance(t, basestring)
+            testlines.append("[%s]" % (t if isinstance(t, str)
                                        else t[0]))
             if isinstance(t, tuple):
                 testlines.extend(t[1:])
@@ -1041,7 +1041,7 @@ add_test({
         try:
             # The actual return value is never checked because we raise.
             self.assertTestResult(True)
-        except Exception, ex:
+        except Exception as ex:
             raised = True
             self.assertEquals(ex.message[0:9], "head file")
 
@@ -1058,7 +1058,7 @@ add_test({
 
         try:
             self.assertTestResult(True)
-        except Exception, ex:
+        except Exception as ex:
             raised = True
             self.assertEquals(ex.message[0:9], "tail file")
 
diff --git a/testing/xpcshell/xpcshellcommandline.py b/testing/xpcshell/xpcshellcommandline.py
index d2a8e6bc13..b106fa058f 100644
--- a/testing/xpcshell/xpcshellcommandline.py
+++ b/testing/xpcshell/xpcshellcommandline.py
@@ -5,7 +5,7 @@ from mozlog import commandline
 
 def add_common_arguments(parser):
     parser.add_argument("--app-path",
-                        type=unicode, dest="appPath", default=None,
+                        type=str, dest="appPath", default=None,
                         help="application directory (as opposed to XRE directory)")
     parser.add_argument("--interactive",
                         action="store_true", dest="interactive", default=False,
@@ -22,7 +22,7 @@ def add_common_arguments(parser):
     parser.add_argument("--dump-tests", type=str, dest="dump_tests", default=None,
                         help="Specify path to a filename to dump all the tests that will be run")
     parser.add_argument("--manifest",
-                        type=unicode, dest="manifest", default=None,
+                        type=str, dest="manifest", default=None,
                         help="Manifest of test directories to use")
     parser.add_argument("--no-logfiles",
                         action="store_false", dest="logfiles",
diff --git a/toolkit/library/dependentlibs.py b/toolkit/library/dependentlibs.py
index 958fe5ef1d..dabd18a50c 100644
--- a/toolkit/library/dependentlibs.py
+++ b/toolkit/library/dependentlibs.py
@@ -29,7 +29,7 @@ def dependentlibs_dumpbin(lib):
     deps = []
     for line in proc.stdout:
         # Each line containing an imported library name starts with 4 spaces
-        match = re.match('    (\S+)', line)
+        match = re.match(r'    (\S+)', line)
         if match:
              deps.append(match.group(1))
         elif len(deps):
@@ -44,7 +44,7 @@ def dependentlibs_mingw_objdump(lib):
     proc = subprocess.Popen(['objdump', '-x', lib], stdout = subprocess.PIPE)
     deps = []
     for line in proc.stdout:
-        match = re.match('\tDLL Name: (\S+)', line)
+        match = re.match('\tDLL Name: (\\S+)', line)
         if match:
             deps.append(match.group(1))
     proc.wait()
@@ -77,13 +77,15 @@ def dependentlibs_readelf(lib):
         # or with BSD readelf:
         #  tag TYPE            value
         # Looking for NEEDED type entries
+        if isinstance(line, bytes):
+            line = line.decode('utf-8', errors='replace')
         tmp = line.split(' ', 3)
         if len(tmp) > 3 and 'NEEDED' in tmp[2]:
             # NEEDED lines look like:
             # 0x00000001 (NEEDED)             Shared library: [libname]
             # or with BSD readelf:
             # 0x00000001 NEEDED               Shared library: [libname]
-            match = re.search('\[(.*)\]', tmp[3])
+            match = re.search(r'\[(.*)\]', tmp[3])
             if match:
                 deps.append(match.group(1))
     proc.wait()
@@ -149,7 +151,7 @@ def gen_list(output, lib):
 
     deps = dependentlibs(lib, libpaths, func)
     deps[lib] = mozpath.join(libpaths[0], lib)
-    output.write('\n'.join(deps.keys()) + '\n')
+    output.write('\n'.join(list(deps.keys())) + '\n')
     return set(deps.values())
 
 def main():
diff --git a/toolkit/mozapps/installer/find-dupes.py b/toolkit/mozapps/installer/find-dupes.py
index 34ef675f49..5fc3a11536 100644
--- a/toolkit/mozapps/installer/find-dupes.py
+++ b/toolkit/mozapps/installer/find-dupes.py
@@ -23,23 +23,23 @@ def find_dupes(source):
         md5s[m][1].append(p)
     total = 0
     num_dupes = 0
-    for m, (size, paths) in md5s.iteritems():
+    for m, (size, paths) in md5s.items():
         if len(paths) > 1:
-            print 'Duplicates %d bytes%s:' % (size,
-                  ' (%d times)' % (len(paths) - 1) if len(paths) > 2 else '')
-            print ''.join('  %s\n' % p for p in paths)
+            print('Duplicates %d bytes%s:' % (size,
+                  ' (%d times)' % (len(paths) - 1) if len(paths) > 2 else ''))
+            print(''.join('  %s\n' % p for p in paths))
             total += (len(paths) - 1) * size
             num_dupes += 1
     if num_dupes:
-        print "WARNING: Found %d duplicated files taking %d bytes" % \
-              (num_dupes, total) + " (uncompressed)"
+        print("WARNING: Found %d duplicated files taking %d bytes" % \
+              (num_dupes, total) + " (uncompressed)")
 
 
 def main():
     if len(sys.argv) != 2:
         import os
-        print >>sys.stderr, "Usage: %s directory" % \
-                            os.path.basename(sys.argv[0])
+        print("Usage: %s directory" % \
+                            os.path.basename(sys.argv[0]), file=sys.stderr)
         sys.exit(1)
 
     find_dupes(sys.argv[1])
diff --git a/toolkit/mozapps/installer/informulate.py b/toolkit/mozapps/installer/informulate.py
index 6af43ac685..eeb7989021 100644
--- a/toolkit/mozapps/installer/informulate.py
+++ b/toolkit/mozapps/installer/informulate.py
@@ -15,7 +15,7 @@ def parse_cmdline(args):
     for arg in args:
         key, s, value = arg.partition("=")
         if s == '':
-            print "ERROR: Malformed command line key value pairing (%s)" % arg
+            print("ERROR: Malformed command line key value pairing (%s)" % arg)
             exit(1)
         contents[key.lower()] = value
     return contents
@@ -23,7 +23,7 @@ def parse_cmdline(args):
 
 def main():
     if len(sys.argv) < 2:
-        print "ERROR: You must specify an output file"
+        print("ERROR: You must specify an output file")
         exit(1)
 
     all_key_value_pairs = {}
@@ -34,7 +34,7 @@ def main():
         'MOZ_APP_VERSION', 'MOZ_APP_MAXVERSION', 'MOZ_APP_ID',
         'CC', 'CXX', 'LD', 'AS']
 
-    all_key_value_pairs = dict([(x.lower(), buildconfig.substs[x]) for x in important_substitutions])
+    all_key_value_pairs = {x.lower(): buildconfig.substs[x] for x in important_substitutions}
     all_key_value_pairs.update(parse_cmdline(sys.argv[2:]))
 
     with open(sys.argv[1], "w+") as f:
diff --git a/toolkit/mozapps/installer/l10n-repack.py b/toolkit/mozapps/installer/l10n-repack.py
index fcf3e773cd..5d214d807f 100644
--- a/toolkit/mozapps/installer/l10n-repack.py
+++ b/toolkit/mozapps/installer/l10n-repack.py
@@ -13,7 +13,7 @@ import buildconfig
 
 # Set of files or directories not listed in a chrome.manifest but that are
 # localized.
-NON_CHROME = set([
+NON_CHROME = {
     '**/crashreporter*.ini',
     'searchplugins',
     'dictionaries',
@@ -24,7 +24,7 @@ NON_CHROME = set([
     'extensions/langpack-*@*',
     'distribution/extensions/langpack-*@*',
     'chrome/**/searchplugins/*.xml',
-])
+}
 
 
 def valid_extra_l10n(arg):
diff --git a/toolkit/mozapps/installer/packager.py b/toolkit/mozapps/installer/packager.py
index 42a66812f9..d75ce8ea6e 100644
--- a/toolkit/mozapps/installer/packager.py
+++ b/toolkit/mozapps/installer/packager.py
@@ -29,11 +29,11 @@ import mozpack.path as mozpath
 import buildconfig
 from argparse import ArgumentParser
 import os
-from StringIO import StringIO
+from io import StringIO
 import subprocess
 import platform
 
-class ToolLauncher(object):
+class ToolLauncher:
     '''
     Helper to execute tools like xpcshell with the appropriate environment.
         launcher = ToolLauncher()
@@ -75,16 +75,16 @@ class ToolLauncher(object):
 
                 vcdir = os.path.abspath(os.path.join(env[e], '../../VC/bin'))
                 if os.path.exists(vcdir):
-                    env['PATH'] = '%s;%s' % (vcdir, env['PATH'])
+                    env['PATH'] = '{};{}'.format(vcdir, env['PATH'])
                     break
 
         # Work around a bug in Python 2.7.2 and lower where unicode types in
         # environment variables aren't handled by subprocess.
         for k, v in env.items():
-            if isinstance(v, unicode):
+            if isinstance(v, str):
                 env[k] = v.encode('utf-8')
 
-        print >>errors.out, 'Executing', ' '.join(cmd)
+        print('Executing', ' '.join(cmd), file=errors.out)
         errors.out.flush()
         return subprocess.call(cmd, env=env)
 
@@ -138,10 +138,11 @@ def precompile_cache(registry, source_path, gre_path, app_path):
         jar = JarReader(cache)
         resource = '/resource/%s/' % resource
         for f in jar:
-            if resource in f.filename:
-                path = f.filename[f.filename.index(resource) + len(resource):]
+            filename = f.filename.decode('utf-8') if isinstance(f.filename, bytes) else f.filename
+            if resource in filename:
+                path = filename[filename.index(resource) + len(resource):]
                 if registry.contains(path):
-                    registry.add(f.filename, GeneratedFile(f.read()))
+                    registry.add(filename, GeneratedFile(f.read()))
         jar.close()
     finally:
         if os.path.exists(cache):
@@ -180,7 +181,7 @@ def split_define(define):
     return (define, 1)
 
 
-class NoPkgFilesRemover(object):
+class NoPkgFilesRemover:
     '''
     Formatter wrapper to handle NO_PKG_FILES.
     '''
diff --git a/toolkit/mozapps/installer/unpack.py b/toolkit/mozapps/installer/unpack.py
index 01a0144229..99e3fedfd3 100644
--- a/toolkit/mozapps/installer/unpack.py
+++ b/toolkit/mozapps/installer/unpack.py
@@ -10,8 +10,8 @@ import buildconfig
 
 def main():
     if len(sys.argv) != 2:
-        print >>sys.stderr, "Usage: %s directory" % \
-                            os.path.basename(sys.argv[0])
+        print("Usage: %s directory" % \
+                            os.path.basename(sys.argv[0]), file=sys.stderr)
         sys.exit(1)
 
     buildconfig.substs['USE_ELF_HACK'] = False
diff --git a/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py b/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py
index cb7303a129..8690d784dc 100644
--- a/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py
+++ b/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py
@@ -37,7 +37,7 @@ def get_locale_strings(path, prefix, middle, add_cr):
              linefeeds when there isn't one already
     """
     output = ""
-    fp = open(path, "r")
+    fp = open(path)
     for line in fp:
         line = line.strip()
         if line == "" or line[0] == "#":
@@ -84,12 +84,12 @@ def preprocess_locale_files(config_dir, l10ndirs):
                                         "LangString ^",
                                         " 0 ",
                                         False)
-    fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
+    fp.write(str(locale_strings, "utf-8").encode("utf-16-le"))
     fp.close()
 
     # Create the Modern User Interface language file
     fp = open_utf16le_file(join(config_dir, "baseLocale.nsh"))
-    fp.write((u""";NSIS Modern User Interface - Language File
+    fp.write((""";NSIS Modern User Interface - Language File
 ;Compatible with Modern UI 1.68
 ;Language: baseLocale (0)
 !insertmacro MOZ_MUI_LANGUAGEFILE_BEGIN \"baseLocale\"
@@ -97,8 +97,8 @@ def preprocess_locale_files(config_dir, l10ndirs):
 """).encode("utf-16-le"))
     locale_strings = get_locale_strings(lookup("mui.properties", l10ndirs),
                                         "!define ", " ", True)
-    fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
-    fp.write(u"!insertmacro MOZ_MUI_LANGUAGEFILE_END\n".encode("utf-16-le"))
+    fp.write(str(locale_strings, "utf-8").encode("utf-16-le"))
+    fp.write("!insertmacro MOZ_MUI_LANGUAGEFILE_END\n".encode("utf-16-le"))
     fp.close()
 
     # Create the custom language file for our custom strings
@@ -108,7 +108,7 @@ def preprocess_locale_files(config_dir, l10ndirs):
                                         "LangString ",
                                         " 0 ",
                                         True)
-    fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
+    fp.write(str(locale_strings, "utf-8").encode("utf-16-le"))
     fp.close()
 
 def create_nlf_file(moz_dir, ab_cd, config_dir):
@@ -124,8 +124,7 @@ def create_nlf_file(moz_dir, ab_cd, config_dir):
 
     # Check whether the locale is right to left from locales.nsi.
     fp = open(join(moz_dir,
-                   "toolkit/mozapps/installer/windows/nsis/locales.nsi"),
-              "r")
+                   "toolkit/mozapps/installer/windows/nsis/locales.nsi"))
     for line in fp:
         line = line.strip()
         if line == "!define " + ab_cd + "_rtl":
@@ -138,7 +137,7 @@ def create_nlf_file(moz_dir, ab_cd, config_dir):
     # along with the default codepage, font name, and font size represented
     # by the '-' character.
     fp = open_utf16le_file(join(config_dir, "baseLocale.nlf"))
-    fp.write((u"""# Header, don't edit
+    fp.write(("""# Header, don't edit
 NLF v6
 # Start editing here
 # Language ID
@@ -175,7 +174,7 @@ def preprocess_locale_file(config_dir,
                                         "LangString ",
                                         " 0 ",
                                         True)
-    fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le"))
+    fp.write(str(locale_strings, "utf-8").encode("utf-16-le"))
     fp.close()
 
 
@@ -187,9 +186,9 @@ def convert_utf8_utf16le(in_file_path, out_file_path):
     in_file_path  - the path to the UTF-8 source file to convert
     out_file_path - the path to the UTF-16LE destination file to create
     """
-    in_fp = open(in_file_path, "r")
+    in_fp = open(in_file_path)
     out_fp = open_utf16le_file(out_file_path)
-    out_fp.write(unicode(in_fp.read(), "utf-8").encode("utf-16-le"))
+    out_fp.write(str(in_fp.read(), "utf-8").encode("utf-16-le"))
     in_fp.close()
     out_fp.close()
 
diff --git a/toolkit/mozapps/update/updater/gen_cert_header.py b/toolkit/mozapps/update/updater/gen_cert_header.py
index 7ecb156197..2db776bb7d 100644
--- a/toolkit/mozapps/update/updater/gen_cert_header.py
+++ b/toolkit/mozapps/update/updater/gen_cert_header.py
@@ -1,5 +1,3 @@
-from __future__ import print_function
-
 import binascii
 
 def file_byte_generator(filename, block_size = 512):
@@ -7,8 +5,7 @@ def file_byte_generator(filename, block_size = 512):
     while True:
       block = f.read(block_size)
       if block:
-        for byte in block:
-          yield byte
+        yield from block
       else:
         break
 
diff --git a/tools/check-moz-style/checkmozstyle.py b/tools/check-moz-style/checkmozstyle.py
index d8261aec5a..6e45192432 100755
--- a/tools/check-moz-style/checkmozstyle.py
+++ b/tools/check-moz-style/checkmozstyle.py
@@ -116,7 +116,7 @@ def process_patch(patch_string, root, cwd, scm):
         cpplint.error("patch", 0, "patch/nodescription", 3,
                       "Patch does not have a description.")
 
-    for filename, diff in patch.files.iteritems():
+    for filename, diff in patch.files.items():
         file_extension = os.path.splitext(filename)[1]
 
         if file_extension in ['.cpp', '.c', '.h']:
diff --git a/tools/check-moz-style/modules/cpplint.py b/tools/check-moz-style/modules/cpplint.py
index c01e82d450..12f1edb9f9 100644
--- a/tools/check-moz-style/modules/cpplint.py
+++ b/tools/check-moz-style/modules/cpplint.py
@@ -851,7 +851,7 @@ def check_for_copyright(filename, lines, error):
 
     # We'll say it should occur by line 10. Don't forget there's a
     # dummy line at the front.
-    for line in xrange(1, min(len(lines), 11)):
+    for line in range(1, min(len(lines), 11)):
         if re.search(r'Copyright|License', lines[line], re.I):
             break
     else:                       # means no copyright line was found
@@ -1391,7 +1391,7 @@ def check_for_function_lengths(filename, clean_lines, line_number,
 
     if starting_func:
         body_found = False
-        for start_line_number in xrange(line_number, clean_lines.num_lines()):
+        for start_line_number in range(line_number, clean_lines.num_lines()):
             start_line = lines[start_line_number]
             joined_line += ' ' + start_line.lstrip()
             if search(r'(;|})', start_line):  # Declarations and trivial functions
@@ -2085,7 +2085,7 @@ def get_line_width(line):
       The width of the line in column positions, accounting for Unicode
       combining characters and wide characters.
     """
-    if isinstance(line, unicode):
+    if isinstance(line, str):
         width = 0
         for c in unicodedata.normalize('NFC', line):
             if unicodedata.east_asian_width(c) in ('W', 'F'):
@@ -2809,7 +2809,7 @@ def check_for_include_what_you_use(filename, clean_lines, include_state, error,
     required = {}  # A map of header name to line_number and the template entity.
         # Example of required: { '': (1219, 'less<>') }
 
-    for line_number in xrange(clean_lines.num_lines()):
+    for line_number in range(clean_lines.num_lines()):
         line = clean_lines.elided[line_number]
         if not line or line[0] == '#':
             continue
@@ -2938,7 +2938,7 @@ def process_file_data(filename, file_extension, lines, error):
 
     remove_multi_line_comments(filename, lines, error)
     clean_lines = CleansedLines(lines)
-    for line in xrange(clean_lines.num_lines()):
+    for line in range(clean_lines.num_lines()):
         process_line(filename, file_extension, clean_lines, line,
                      include_state, function_state, class_state, error)
     class_state.check_finished(filename, error)
diff --git a/tools/check-moz-style/modules/logging.py b/tools/check-moz-style/modules/logging.py
index ea03a489c6..42d7148bbf 100644
--- a/tools/check-moz-style/modules/logging.py
+++ b/tools/check-moz-style/modules/logging.py
@@ -29,10 +29,11 @@
 #
 # WebKit's Python module for logging
 
+from __future__ import print_function
 import sys
 
 def log(string):
-    print >> sys.stderr, string
+    print(string, file=sys.stderr)
 
 def error(string):
     log("ERROR: " + string)
diff --git a/tools/check-moz-style/modules/scm.py b/tools/check-moz-style/modules/scm.py
index e7cb9ffc60..07b9aa3ddd 100644
--- a/tools/check-moz-style/modules/scm.py
+++ b/tools/check-moz-style/modules/scm.py
@@ -29,6 +29,7 @@
 #
 # Python module for interacting with an SCM system (like SVN or Git)
 
+from __future__ import print_function
 import os
 import re
 import subprocess
@@ -118,7 +119,7 @@ class SCM:
 
     def ensure_clean_working_directory(self, force):
         if not force and not self.working_directory_is_clean():
-            print self.run_command(self.status_command(), raise_on_failure=False)
+            print(self.run_command(self.status_command(), raise_on_failure=False))
             error("Working directory has modifications, pass --force-clean or --no-clean to continue.")
         
         log("Cleaning working directory")
@@ -157,45 +158,45 @@ class SCM:
 
     @staticmethod
     def in_working_directory(path):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     @staticmethod
     def find_checkout_root(path):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     @staticmethod
     def commit_success_regexp():
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def working_directory_is_clean(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def clean_working_directory(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def update_webkit(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def status_command(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def changed_files(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def display_name(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def create_patch(self):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def commit_with_message(self, message):
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
     
     # Subclasses must indicate if they support local commits,
     # but the SCM baseclass will only call local_commits methods when this is true.
     @staticmethod
     def supports_local_commits():
-        raise NotImplementedError, "subclasses must implement"
+        raise NotImplementedError("subclasses must implement")
 
     def create_patch_from_local_commit(self, commit_id):
         pass
diff --git a/tools/lint/eslint.lint b/tools/lint/eslint.lint
index a2d864f75f..9b14160403 100644
--- a/tools/lint/eslint.lint
+++ b/tools/lint/eslint.lint
@@ -10,8 +10,31 @@ import re
 import signal
 import subprocess
 import sys
-from distutils.version import LooseVersion
-
+try:
+    from distutils.version import LooseVersion
+except ImportError:
+    import re as _re
+    class LooseVersion:
+        def __init__(self, vstring):
+            self.vstring = vstring
+            self.version = [int(x) if x.isdigit() else x for x in _re.split(r'[.\-]', vstring)]
+        def __str__(self): return self.vstring
+        def __repr__(self): return "LooseVersion ('%s')" % str(self)
+        def _cmp(self, other):
+            if not isinstance(other, LooseVersion): other = LooseVersion(other)
+            a, b = self.version, other.version
+            for i in range(max(len(a), len(b))):
+                va = a[i] if i < len(a) else 0
+                vb = b[i] if i < len(b) else 0
+                if type(va) != type(vb): va, vb = str(va), str(vb)
+                if va < vb: return -1
+                if va > vb: return 1
+            return 0
+        def __eq__(self, other): return self._cmp(other) == 0
+        def __lt__(self, other): return self._cmp(other) < 0
+        def __le__(self, other): return self._cmp(other) <= 0
+        def __gt__(self, other): return self._cmp(other) > 0
+        def __ge__(self, other): return self._cmp(other) >= 0
 import which
 from mozprocess import ProcessHandler
 
diff --git a/tools/mach_commands.py b/tools/mach_commands.py
index 898073bb63..1c67fa68bb 100644
--- a/tools/mach_commands.py
+++ b/tools/mach_commands.py
@@ -4,6 +4,7 @@
 
 from __future__ import absolute_import, unicode_literals
 
+from __future__ import print_function
 import sys
 import os
 import stat
@@ -75,9 +76,9 @@ class UUIDProvider(object):
                 print('')
         if format in [None, 'cpp', 'c++']:
             u = u.hex
-            print('{ 0x%s, 0x%s, 0x%s, \\' % (u[0:8], u[8:12], u[12:16]))
-            pairs = tuple(map(lambda n: u[n:n+2], range(16, 32, 2)))
-            print(('  { ' + '0x%s, ' * 7 + '0x%s } }') % pairs)
+            print(('{ 0x%s, 0x%s, 0x%s, \\' % (u[0:8], u[8:12], u[12:16])))
+            pairs = tuple([u[n:n+2] for n in range(16, 32, 2)])
+            print((('  { ' + '0x%s, ' * 7 + '0x%s } }') % pairs))
 
 
 @CommandProvider
@@ -92,7 +93,7 @@ class RageProvider(MachCommandBase):
         form where you can submit feedback. Just close the tab when done.
         """
         import getpass
-        import urllib
+        import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
         import webbrowser
 
         # Try to resolve the current user.
@@ -127,7 +128,7 @@ class RageProvider(MachCommandBase):
 
         url = 'https://docs.google.com/a/mozilla.com/forms/d/e/1FAIpQLSeDVC3IXJu5d33Hp_ZTCOw06xEUiYH1pBjAqJ1g_y63sO2vvA/viewform'
         if user:
-            url += '?entry.1281044204=%s' % urllib.quote(user)
+            url += '?entry.1281044204=%s' % six.moves.urllib.parse.quote(user)
 
         print('Please leave your feedback in the opened web form')
         webbrowser.open_new_tab(url)
@@ -148,8 +149,8 @@ class PastebinProvider(object):
                      help='Specify the file to upload to pastebin.mozilla.org')
 
     def pastebin(self, language, poster, duration, file):
-        import urllib
-        import urllib2
+        import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
+        import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 
         URL = 'https://pastebin.mozilla.org/'
 
@@ -183,7 +184,7 @@ class PastebinProvider(object):
                 extension = file.split('.')[-1]
                 for l in FILE_TYPES:
                     if extension == l['extension']:
-                        print('Identified file as %s' % l['name'])
+                        print(('Identified file as %s' % l['name']))
                         lang = l['value']
             except IOError:
                 print('ERROR. No such file')
@@ -204,18 +205,18 @@ class PastebinProvider(object):
             ('expiry', duration),
             ('paste', 'Send')]
 
-        data = urllib.urlencode(params)
+        data = six.moves.urllib.parse.urlencode(params)
         print('Uploading ...')
         try:
-            req = urllib2.Request(URL, data)
-            response = urllib2.urlopen(req)
+            req = six.moves.urllib.request.Request(URL, data)
+            response = six.moves.urllib.request.urlopen(req)
             http_response_code = response.getcode()
             if http_response_code == 200:
-                print(response.geturl())
+                print((response.geturl()))
             else:
-                print('Could not upload the file, '
-                      'HTTP Response Code %s' %(http_response_code))
-        except urllib2.URLError:
+                print(('Could not upload the file, '
+                      'HTTP Response Code %s' %(http_response_code)))
+        except six.moves.urllib.error.URLError:
             print('ERROR. Could not connect to pastebin.mozilla.org.')
             return 1
         return 0
@@ -228,7 +229,7 @@ class FormatProvider(MachCommandBase):
     @CommandArgument('--show', '-s', action = 'store_true',
         help = 'Show diff output on instead of applying changes')
     def clang_format(self, show=False):
-        import urllib2
+        import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 
         plat = platform.system()
         fmt = plat.lower() + "/clang-format-3.5"
@@ -242,8 +243,8 @@ class FormatProvider(MachCommandBase):
         else:
             arch = os.uname()[4]
             if (plat != "Linux" and plat != "Darwin") or arch != 'x86_64':
-                print("Unsupported platform " + plat + "/" + arch +
-                      ". Supported platforms are Windows/*, Linux/x86_64 and Darwin/x86_64")
+                print(("Unsupported platform " + plat + "/" + arch +
+                      ". Supported platforms are Windows/*, Linux/x86_64 and Darwin/x86_64"))
                 return 1
 
         os.chdir(self.topsrcdir)
@@ -256,8 +257,8 @@ class FormatProvider(MachCommandBase):
             if not clang_format_diff:
                 return 1
 
-        except urllib2.HTTPError as e:
-            print("HTTP error {0}: {1}".format(e.code, e.reason))
+        except six.moves.urllib.error.HTTPError as e:
+            print(("HTTP error {0}: {1}".format(e.code, e.reason)))
             return 1
 
         from subprocess import Popen, PIPE
@@ -276,7 +277,7 @@ class FormatProvider(MachCommandBase):
                 if e.errno == errno.ENOENT:
                     print("Can't find filterdiff. Please install patchutils.")
                 else:
-                    print("OSError {0}: {1}".format(e.code, e.reason))
+                    print(("OSError {0}: {1}".format(e.code, e.reason)))
                 return 1
 
 
@@ -290,14 +291,14 @@ class FormatProvider(MachCommandBase):
         target = os.path.join(self._mach_context.state_dir, os.path.basename(root))
         if not os.path.exists(target):
             site = "https://people.mozilla.org/~ajones/clang-format/"
-            if self.prompt and raw_input("Download clang-format executables from {0} (yN)? ".format(site)).lower() != 'y':
+            if self.prompt and input("Download clang-format executables from {0} (yN)? ".format(site)).lower() != 'y':
                 print("Download aborted.")
                 return 1
             self.prompt = False
 
             u = site + root
-            print("Downloading {0} to {1}".format(u, target))
-            data = urllib2.urlopen(url=u).read()
+            print(("Downloading {0} to {1}".format(u, target)))
+            data = six.moves.urllib.request.urlopen(url=u).read()
             temp = target + ".tmp"
             with open(temp, "wb") as fh:
                 fh.write(data)
@@ -340,8 +341,8 @@ def mozregression_create_parser():
                 'install',
                 'mozregression==%s' % release
             ])
-            print("mozregression was updated to version %s. please"
-                  " re-run your command." % release)
+            print(("mozregression was updated to version %s. please"
+                  " re-run your command." % release))
         else:
             # mozregression is up to date, return the parser.
             return mozregression.parser()
diff --git a/tools/power/mach_commands.py b/tools/power/mach_commands.py
index 281e7a868e..587e717a39 100644
--- a/tools/power/mach_commands.py
+++ b/tools/power/mach_commands.py
@@ -4,7 +4,7 @@
 
 from __future__ import print_function
 
-from distutils.version import StrictVersion
+# StrictVersion replaced
 
 from mach.decorators import (
     Command,
diff --git a/tools/profiler/merge-profiles.py b/tools/profiler/merge-profiles.py
index 0c10c60e1d..5037030841 100755
--- a/tools/profiler/merge-profiles.py
+++ b/tools/profiler/merge-profiles.py
@@ -5,6 +5,7 @@
 # is used to syncronized the samples. Each thread is moved into the merged
 # profile.
 #
+from __future__ import print_function
 import json
 import re
 import sys
@@ -107,7 +108,7 @@ if len(sys.argv) > 1:
     MergeProfiles(sys.argv[1:])
     sys.exit(0)
 
-print "Usage: merge-profile.py profile__.sym profile__.sym > merged.sym"
+print("Usage: merge-profile.py profile__.sym profile__.sym > merged.sym")
 
 
 
diff --git a/tools/profiler/nm-symbolicate.py b/tools/profiler/nm-symbolicate.py
index f51d7f75f5..9b380ad9df 100755
--- a/tools/profiler/nm-symbolicate.py
+++ b/tools/profiler/nm-symbolicate.py
@@ -4,6 +4,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import sys, subprocess, os
 
 def NMSymbolicate(library, addresses):
@@ -34,15 +35,15 @@ def NMSymbolicate(library, addresses):
         symbolForAddress = symbol
         break
     if symbolForAddress:
-      print symbolForAddress["funcName"]
+      print(symbolForAddress["funcName"])
     else:
-      print "??" # match addr2line
-    print ":0" # no line information from nm
+      print("??") # match addr2line
+    print(":0") # no line information from nm
 
 if len(sys.argv) > 1:
     NMSymbolicate(sys.argv[1], sys.argv[2:])
     sys.exit(0)
 
-print "Usage: nm-symbolicate.py   > merged.sym"
+print("Usage: nm-symbolicate.py   > merged.sym")
 
 
diff --git a/tools/rb/find_leakers.py b/tools/rb/find_leakers.py
index 4405d7a179..3f32f7d4b6 100755
--- a/tools/rb/find_leakers.py
+++ b/tools/rb/find_leakers.py
@@ -10,21 +10,22 @@
 # Please see README file in the same directory.
 
 
+from __future__ import print_function
 import sys
 
 def print_output(allocation, obj_to_class):
     '''Formats and prints output.'''
     items = []
-    for obj, count, in allocation.iteritems():
+    for obj, count, in allocation.items():
         # Adding items to a list, so we can sort them.
         items.append((obj, count))
     # Sorting by count.
     items.sort(key=lambda item: item[1])
 
     for obj, count, in items:
-        print "{obj} ({count}) @ {class_name}".format(obj=obj,
+        print("{obj} ({count}) @ {class_name}".format(obj=obj,
                                                       count=count,
-                                                      class_name=obj_to_class[obj])
+                                                      class_name=obj_to_class[obj]))
 
 def process_log(log_lines):
     '''Process through the log lines, and print out the result.
@@ -63,8 +64,8 @@ def process_log(log_lines):
             #      0x01AFD3B8 1 Release 0
             #      0x08880BD0 8 Dtor (20)
             if obj not in allocation:
-                print "An object was released that wasn't allocated!",
-                print obj, "@", class_name
+                print("An object was released that wasn't allocated!", end=' ')
+                print(obj, "@", class_name)
             else:
                 allocation.pop(obj)
             obj_to_class.pop(obj)
@@ -74,12 +75,12 @@ def process_log(log_lines):
 
 
 def print_usage():
-    print
-    print "Usage: find-leakers.py [log-file]"
-    print
-    print "If `log-file' provided, it will read that as the input log."
-    print "Else, it will read the stdin as the input log."
-    print
+    print()
+    print("Usage: find-leakers.py [log-file]")
+    print()
+    print("If `log-file' provided, it will read that as the input log.")
+    print("Else, it will read the stdin as the input log.")
+    print()
 
 def main():
     '''Main method of the script.'''
@@ -92,7 +93,7 @@ def main():
             log_lines = log_file.readlines()
         process_log(log_lines)
     else:
-        print 'ERROR: Invalid number of arguments'
+        print('ERROR: Invalid number of arguments')
         print_usage()
 
 if __name__ == '__main__':
diff --git a/tools/rb/fix_linux_stack.py b/tools/rb/fix_linux_stack.py
index 146e6eebdf..64a0ca76ae 100755
--- a/tools/rb/fix_linux_stack.py
+++ b/tools/rb/fix_linux_stack.py
@@ -7,6 +7,7 @@
 # produced by NS_FormatCodeAddress(), which on Linux often lack a function
 # name, a file name and a line number.
 
+from __future__ import print_function
 import subprocess
 import sys
 import re
@@ -40,7 +41,7 @@ class unbufferedLineConverter:
     def test():
         assert unbufferedLineConverter("rev").convert("123") == "321"
         assert unbufferedLineConverter("cut", ["-c3"]).convert("abcde") == "c"
-        print "Pass"
+        print("Pass")
 
 objdump_section_re = re.compile("^ [0-9a-f]* ([0-9a-f ]{8}) ([0-9a-f ]{8}) ([0-9a-f ]{8}) ([0-9a-f ]{8}).*")
 def elf_section(file, section):
@@ -173,11 +174,11 @@ def separate_debug_file_for(file):
 
     def word32(s):
         if type(s) != str or len(s) != 4:
-            raise StandardError("expected 4 byte string input")
+            raise Exception("expected 4 byte string input")
         s = list(s)
         if endian == "big":
             s.reverse()
-        return sum(map(lambda idx: ord(s[idx]) * (256 ** idx), range(0, 4)))
+        return sum([ord(s[idx]) * (256 ** idx) for idx in range(0, 4)])
 
     buildid = elf_section(file, ".note.gnu.build-id");
     if buildid is not None:
@@ -192,7 +193,7 @@ def separate_debug_file_for(file):
            note_header[12:16] != "GNU\0":
             sys.stderr.write("malformed .note.gnu.build_id in " + file + "\n")
         else:
-            buildid = "".join(map(lambda ch: "%02X" % ord(ch), buildid)).lower()
+            buildid = "".join(["%02X" % ord(ch) for ch in buildid]).lower()
             f = os.path.join(global_debug_dir, ".build-id", buildid[0:2], buildid[2:] + ".debug")
             if have_debug_file(f):
                 return f
diff --git a/tools/rb/fix_macosx_stack.py b/tools/rb/fix_macosx_stack.py
index 32831e9134..e1b63a8675 100755
--- a/tools/rb/fix_macosx_stack.py
+++ b/tools/rb/fix_macosx_stack.py
@@ -7,6 +7,7 @@
 # NS_FormatCodeAddress(), which on Mac often lack a file name and a line
 # number.
 
+from __future__ import print_function
 import subprocess
 import sys
 import re
@@ -39,7 +40,7 @@ class unbufferedLineConverter:
     def test():
         assert unbufferedLineConverter("rev").convert("123") == "321"
         assert unbufferedLineConverter("cut", ["-c3"]).convert("abcde") == "c"
-        print "Pass"
+        print("Pass")
 
 def separate_debug_file_for(file):
     return None
@@ -56,13 +57,13 @@ def address_adjustment(file):
             if line == "  segname __TEXT\n":
                 line = otool.stdout.readline()
                 if not line.startswith("   vmaddr "):
-                    raise StandardError("unexpected otool output")
+                    raise Exception("unexpected otool output")
                 result = int(line[10:], 16)
                 break
         otool.stdout.close()
 
         if result is None:
-            raise StandardError("unexpected otool output")
+            raise Exception("unexpected otool output")
 
         address_adjustments[file] = result
 
diff --git a/tools/rb/fix_stack_using_bpsyms.py b/tools/rb/fix_stack_using_bpsyms.py
index 5d04cd02a1..798aaf8fc7 100755
--- a/tools/rb/fix_stack_using_bpsyms.py
+++ b/tools/rb/fix_stack_using_bpsyms.py
@@ -10,6 +10,7 @@
 
 from __future__ import with_statement
 
+from __future__ import print_function
 import sys
 import os
 import re
@@ -160,4 +161,4 @@ def fixSymbols(line, symbolsDir):
 if __name__ == "__main__":
   symbolsDir = sys.argv[1]
   for line in iter(sys.stdin.readline, ''):
-    print fixSymbols(line, symbolsDir),
+    print(fixSymbols(line, symbolsDir), end=' ')
diff --git a/tools/update-packaging/generatesnippet.py b/tools/update-packaging/generatesnippet.py
index 15b7edf588..8fb2abbe44 100644
--- a/tools/update-packaging/generatesnippet.py
+++ b/tools/update-packaging/generatesnippet.py
@@ -7,9 +7,10 @@ This script generates the complete snippet for a given locale or en-US
 Most of the parameters received are to generate the MAR's download URL
 and determine the MAR's filename
 """
+from __future__ import print_function
 import sys, os, platform, sha
 from optparse import OptionParser
-from ConfigParser import ConfigParser
+from configparser import ConfigParser
 from stat import ST_SIZE
 
 def main():
@@ -80,7 +81,7 @@ def main():
 
     if options.verbose:
         # Show in our logs what the contents of the snippet are
-        print snippet
+        print(snippet)
 
 def generateSnippet(abstDistDir, applicationIniFile, locale,
                     downloadBaseURL, product, platform, branch):
@@ -88,7 +89,8 @@ def generateSnippet(abstDistDir, applicationIniFile, locale,
     c = ConfigParser()
     try:
         c.readfp(open(applicationIniFile))
-    except IOError, (stderror):
+    except IOError as xxx_todo_changeme:
+       (stderror) = xxx_todo_changeme
        sys.exit(stderror)
     buildid = c.get("App", "BuildID")
     appVersion = c.get("App", "Version")
@@ -141,7 +143,8 @@ def getFileHashAndSize(filepath):
         shaObj = sha.new(f.read())
         sha1Hash = shaObj.hexdigest()
         size = os.stat(filepath)[ST_SIZE]
-    except IOError, (stderror):
+    except IOError as xxx_todo_changeme1:
+       (stderror) = xxx_todo_changeme1
        sys.exit(stderror)
 
     return (sha1Hash, size)
diff --git a/tools/update-packaging/make_incremental_updates.py b/tools/update-packaging/make_incremental_updates.py
index dc7b3a01ea..07cfe5bcb6 100755
--- a/tools/update-packaging/make_incremental_updates.py
+++ b/tools/update-packaging/make_incremental_updates.py
@@ -2,6 +2,7 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
 import os
 import shutil
 import hashlib
@@ -46,11 +47,11 @@ class PatchInfo:
         if m:
             # Directory immediately following extensions is used for the test
             testdir = m.group(1)
-            print '     add-if "'+testdir+'" "'+filename+'"'
+            print('     add-if "'+testdir+'" "'+filename+'"')
             self.manifestv2.append('add-if "'+testdir+'" "'+filename+'"')
             self.manifestv3.append('add-if "'+testdir+'" "'+filename+'"')
         else:
-            print '        add "'+filename+'"'
+            print('        add "'+filename+'"')
             self.manifestv2.append('add "'+filename+'"')
             self.manifestv3.append('add "'+filename+'"')
 
@@ -59,7 +60,7 @@ class PatchInfo:
             This was ported from mozilla/tools/update-packaging/common.sh's
             make_add_if_not_instruction.
         """
-        print ' add-if-not "'+filename+'" "'+filename+'"'
+        print(' add-if-not "'+filename+'" "'+filename+'"')
         self.manifestv3.append('add-if-not "'+filename+'" "'+filename+'"')
 
     def append_patch_instruction(self, filename, patchname):
@@ -76,11 +77,11 @@ class PatchInfo:
         m = re.match("((?:|.*/)distribution/extensions/.*)/", filename)
         if m:
             testdir = m.group(1)
-            print '   patch-if "'+testdir+'" "'+patchname+'" "'+filename+'"'
+            print('   patch-if "'+testdir+'" "'+patchname+'" "'+filename+'"')
             self.manifestv2.append('patch-if "'+testdir+'" "'+patchname+'" "'+filename+'"')
             self.manifestv3.append('patch-if "'+testdir+'" "'+patchname+'" "'+filename+'"')
         else:
-            print '      patch "'+patchname+'" "'+filename+'"'
+            print('      patch "'+patchname+'" "'+filename+'"')
             self.manifestv2.append('patch "'+patchname+'" "'+filename+'"')
             self.manifestv3.append('patch "'+patchname+'" "'+filename+'"')
 
@@ -90,16 +91,16 @@ class PatchInfo:
             mozilla/tools/update-packaging/common.sh/make_remove_instruction
         """
         if filename.endswith("/"):
-            print '      rmdir "'+filename+'"'
+            print('      rmdir "'+filename+'"')
             self.manifestv2.append('rmdir "'+filename+'"')
             self.manifestv3.append('rmdir "'+filename+'"')
         elif filename.endswith("/*"):
             filename = filename[:-1]
-            print '    rmrfdir "'+filename+'"'
+            print('    rmrfdir "'+filename+'"')
             self.manifestv2.append('rmrfdir "'+filename+'"')
             self.manifestv3.append('rmrfdir "'+filename+'"')
         else:
-            print '     remove "'+filename+'"'
+            print('     remove "'+filename+'"')
             self.manifestv2.append('remove "'+filename+'"')
             self.manifestv3.append('remove "'+filename+'"')
 
@@ -217,7 +218,7 @@ def xzunzip_file(filename):
 def extract_mar(filename, work_dir):
     """ Extracts the marfile intot he work_dir
         assumes work_dir already exists otherwise will throw osError"""
-    print "Extracting "+filename+" to "+work_dir
+    print("Extracting "+filename+" to "+work_dir)
     saved_path = os.getcwd()
     try:
         os.chdir(work_dir)
@@ -229,7 +230,7 @@ def create_partial_patch_for_file(from_marfile_entry, to_marfile_entry, shas, pa
     """ Creates the partial patch file and manifest entry for the pair of files passed in
     """
     if not (from_marfile_entry.sha(),to_marfile_entry.sha()) in shas:
-        print 'diffing "'+from_marfile_entry.name+'\"'
+        print('diffing "'+from_marfile_entry.name+'\"')
         #bunzip to/from
         bunzip_file(from_marfile_entry.abs_path)
         bunzip_file(to_marfile_entry.abs_path)
@@ -343,7 +344,7 @@ def create_partial_patch(from_dir_path, to_dir_path, patch_filename, shas, patch
     elif "Contents\Resources\precomplete" in to_file_set:
         forced_list.append("Contents\Resources\precomplete")
     else:
-        raise Exception, "missing precomplete file in: "+to_dir_path
+        raise Exception("missing precomplete file in: "+to_dir_path)
 
     if "removed-files" in to_file_set:
         forced_list.append("removed-files")
@@ -353,7 +354,7 @@ def create_partial_patch(from_dir_path, to_dir_path, patch_filename, shas, patch
     elif "Contents\Resources\\removed-files" in to_file_set:
         forced_list.append("Contents\Resources\\removed-files")
     else:
-        raise Exception, "missing removed-files file in: "+to_dir_path
+        raise Exception("missing removed-files file in: "+to_dir_path)
 
     if "chrome.manifest" in to_file_set:
         forced_list.append("chrome.manifest")
@@ -363,7 +364,7 @@ def create_partial_patch(from_dir_path, to_dir_path, patch_filename, shas, patch
     elif "Contents\Resources\\chrome.manifest" in to_file_set:
         forced_list.append("Contents\Resources\\chrome.manifest")
     else:
-        raise Exception, "missing chrome.manifest file in: "+to_dir_path
+        raise Exception("missing chrome.manifest file in: "+to_dir_path)
 
     # Files which exist in both sets need to be patched
     patch_filenames = list(from_file_set.intersection(to_file_set))
@@ -375,7 +376,7 @@ def create_partial_patch(from_dir_path, to_dir_path, patch_filename, shas, patch
             # This filename is in the add if not list, explicitly add-if-not
             create_add_if_not_patch_for_file(to_dir_hash[filename], patch_info)
         elif filename in forced_list:
-            print 'Forcing "'+filename+'"'
+            print('Forcing "'+filename+'"')
             # This filename is in the forced list, explicitly add
             create_add_patch_for_file(to_dir_hash[filename], patch_info)
         else:
@@ -422,8 +423,8 @@ def create_partial_patch(from_dir_path, to_dir_path, patch_filename, shas, patch
     return patch_filename
 
 def usage():
-    print "-h for help"
-    print "-f for patchlist_file"
+    print("-h for help")
+    print("-f for patchlist_file")
 
 def get_buildid(work_dir):
     """ extracts buildid from MAR
@@ -432,7 +433,7 @@ def get_buildid(work_dir):
     if not os.path.exists(ini):
         ini = '%s/Contents/Resources/application.ini' % work_dir
         if not os.path.exists(ini):
-            print 'WARNING: application.ini not found, cannot find build ID'
+            print('WARNING: application.ini not found, cannot find build ID')
             return ''
 
     fd, tmppath = tempfile.mkstemp('', 'tmp', os.getcwd())
@@ -460,7 +461,7 @@ def decode_filename(filepath):
         '(?P\w+)(-)(?P\w+\.\w+(\.\w+){0,2})(\.)(?P.+?)(\.)(?P.+?)(\.)(?P\w+)(.mar)',
       os.path.basename(filepath))
       return m.groupdict()
-    except Exception, exc:
+    except Exception as exc:
       try:
         m = re.search(
           '(?P.+?)\/(?P.+?)\/(?P\w+)-(?P\w+\.\w+)\.(?P\w+).mar',
@@ -477,7 +478,7 @@ def create_partial_patches(patches):
     metadata = []
     try:
         work_dir_root = tempfile.mkdtemp('-fastmode', 'tmp', os.getcwd())
-        print "Building patches using work dir: %s" % (work_dir_root)
+        print("Building patches using work dir: %s" % (work_dir_root))
 
         # Iterate through every patch set in the patch file
         patch_num = 1
@@ -533,7 +534,7 @@ def create_partial_patches(patches):
              'locale':from_decoded['locale'],
              'platform':from_decoded['platform'],
             })
-            print "done with patch %s/%s time (%.2fs/%.2fs/%.2fs) (mar/patch/total)" % (str(patch_num),str(len(patches)),mar_extract_time-startTime,time.time()-mar_extract_time,time.time()-startTime)
+            print("done with patch %s/%s time (%.2fs/%.2fs/%.2fs) (mar/patch/total)" % (str(patch_num),str(len(patches)),mar_extract_time-startTime,time.time()-mar_extract_time,time.time()-startTime))
             patch_num += 1
         return metadata
     finally:
diff --git a/xpcom/idl-parser/xpidl/header.py b/xpcom/idl-parser/xpidl/header.py
index 8e854c4da8..9e5fe08e31 100644
--- a/xpcom/idl-parser/xpidl/header.py
+++ b/xpcom/idl-parser/xpidl/header.py
@@ -10,7 +10,7 @@
 import sys
 import os.path
 import re
-import xpidl
+from . import xpidl
 import itertools
 import glob
 
@@ -410,7 +410,7 @@ def write_interface(iface, fd):
 
     names = uuid_decoder.match(iface.attributes.uuid).groupdict()
     m3str = names['m3'] + names['m4']
-    names['m3joined'] = ", ".join(["0x%s" % m3str[i:i+2] for i in xrange(0, 16, 2)])
+    names['m3joined'] = ", ".join(["0x%s" % m3str[i:i+2] for i in range(0, 16, 2)])
 
     if iface.name[2] == 'I':
         implclass = iface.name[:2] + iface.name[3:]
diff --git a/xpcom/idl-parser/xpidl/runtests.py b/xpcom/idl-parser/xpidl/runtests.py
index 89222d5467..42d596766f 100644
--- a/xpcom/idl-parser/xpidl/runtests.py
+++ b/xpcom/idl-parser/xpidl/runtests.py
@@ -7,8 +7,8 @@
 
 import mozunit
 import unittest
-import xpidl
-import header
+from . import xpidl
+from . import header
 
 
 class TestParser(unittest.TestCase):
diff --git a/xpcom/idl-parser/xpidl/typelib.py b/xpcom/idl-parser/xpidl/typelib.py
index 911e3873da..79d2d30964 100644
--- a/xpcom/idl-parser/xpidl/typelib.py
+++ b/xpcom/idl-parser/xpidl/typelib.py
@@ -7,9 +7,10 @@
 
 """Generate an XPIDL typelib for the IDL files specified on the command line"""
 
+from __future__ import print_function
 import os
 import sys
-import xpidl
+from . import xpidl
 import xpt
 
 # A map of xpidl.py types to xpt.py types
@@ -274,14 +275,14 @@ if __name__ == '__main__':
 
     if options.regen:
         if options.cachedir is None:
-            print >>sys.stderr, "--regen requires --cachedir"
+            print("--regen requires --cachedir", file=sys.stderr)
             sys.exit(1)
 
         p = xpidl.IDLParser(outputdir=options.cachedir, regen=True)
         sys.exit(0)
 
     if options.depfile is not None and options.outfile is None:
-        print >>sys.stderr, "-d requires -o"
+        print("-d requires -o", file=sys.stderr)
         sys.exit(1)
 
     if options.outfile is not None:
@@ -302,6 +303,6 @@ if __name__ == '__main__':
         depfd = open(options.depfile, 'w')
         deps = [dep.replace('\\', '/') for dep in idl.deps]
 
-        print >>depfd, "%s: %s" % (options.outfile, " ".join(deps))
+        print("%s: %s" % (options.outfile, " ".join(deps)), file=depfd)
         for dep in deps:
-            print >>depfd, "%s:" % dep
+            print("%s:" % dep, file=depfd)
diff --git a/xpcom/idl-parser/xpidl/xpidl.py b/xpcom/idl-parser/xpidl/xpidl.py
index 6bb1ad5de5..99e508fbb6 100755
--- a/xpcom/idl-parser/xpidl/xpidl.py
+++ b/xpcom/idl-parser/xpidl/xpidl.py
@@ -7,6 +7,7 @@
 
 """A parser for cross-platform IDL (XPIDL) files."""
 
+from __future__ import print_function
 import sys
 import os.path
 import re
@@ -36,7 +37,7 @@ def attlistToIDL(attlist):
         return ''
 
     attlist = list(attlist)
-    attlist.sort(cmp=lambda a, b: cmp(a[0], b[0]))
+    attlist.sort(key=lambda a: a[0])
 
     return '[%s] ' % ','.join(["%s%s" % (name, value is not None and '(%s)' % value or '')
                               for name, value, aloc in attlist])
@@ -113,7 +114,7 @@ class Builtin(object):
 
     def nativeType(self, calltype, shared=False, const=False):
         if const:
-            print >>sys.stderr, IDLError("[const] doesn't make sense on builtin types.", self.location, warning=True)
+            print(IDLError("[const] doesn't make sense on builtin types.", self.location, warning=True), file=sys.stderr)
             const = 'const '
         elif calltype == 'in' and self.nativename.endswith('*'):
             const = 'const '
@@ -173,7 +174,7 @@ class Location(object):
 
     def pointerline(self):
         def i():
-            for i in xrange(0, self._colno):
+            for i in range(0, self._colno):
                 yield " "
             yield "^"
 
@@ -201,7 +202,7 @@ class NameMap(object):
         return self._d[key]
 
     def __iter__(self):
-        return self._d.itervalues()
+        return iter(self._d.values())
 
     def __contains__(self, key):
         return key in builtinMap or key in self._d
@@ -374,10 +375,10 @@ class Forward(object):
         # Hack alert: if an identifier is already present, move the doccomments
         # forward.
         if parent.hasName(self.name):
-            for i in xrange(0, len(parent.productions)):
+            for i in range(0, len(parent.productions)):
                 if parent.productions[i] is self:
                     break
-            for i in xrange(i + 1, len(parent.productions)):
+            for i in range(i + 1, len(parent.productions)):
                 if hasattr(parent.productions[i], 'doccomments'):
                     parent.productions[i].doccomments[0:0] = self.doccomments
                     break
@@ -422,7 +423,7 @@ class Native(object):
                 if self.modifier is not None:
                     raise IDLError("More than one ptr/ref modifier", aloc)
                 self.modifier = name
-            elif name in self.specialtypes.keys():
+            elif name in list(self.specialtypes.keys()):
                 if self.specialtype is not None:
                     raise IDLError("More than one special type", aloc)
                 self.specialtype = name
@@ -516,7 +517,7 @@ class Interface(object):
         if self.attributes.function:
             has_method = False
             for member in self.members:
-                if member.kind is 'method':
+                if member.kind == 'method':
                     if has_method:
                         raise IDLError("interface '%s' has multiple methods, but marked 'function'" % self.name, self.location)
                     else:
@@ -1003,9 +1004,9 @@ class Param(object):
 
         try:
             return self.realtype.nativeType(self.paramtype, **kwargs)
-        except IDLError, e:
+        except IDLError as e:
             raise IDLError(e.message, self.location)
-        except TypeError, e:
+        except TypeError as e:
             raise IDLError("Unexpected parameter attribute", self.location)
 
     def toIDL(self):
@@ -1053,7 +1054,7 @@ class IDLParser(object):
         'NATIVEID',
         ]
 
-    tokens.extend(keywords.values())
+    tokens.extend(list(keywords.values()))
 
     states = (
         ('nativeid', 'exclusive'),
@@ -1071,13 +1072,13 @@ class IDLParser(object):
     t_ignore = ' \t'
 
     def t_multilinecomment(self, t):
-        r'/\*(?s).*?\*/'
+        r'/\*.*?\*/'
         t.lexer.lineno += t.value.count('\n')
         if t.value.startswith("/**"):
             self._doccomments.append(t.value)
 
     def t_singlelinecomment(self, t):
-        r'(?m)//.*?$'
+        r'//[^\n]*'
 
     def t_IID(self, t):
         return t
@@ -1089,7 +1090,7 @@ class IDLParser(object):
         return t
 
     def t_LCDATA(self, t):
-        r'(?s)%\{[ ]*C\+\+[ ]*\n(?P.*?\n?)%\}[ ]*(C\+\+)?'
+        r'%\{[ ]*C\+\+[ ]*\n(?P.*?\n?)%\}[ ]*(C\+\+)?'
         t.type = 'CDATA'
         t.value = t.lexer.lexmatch.group('cdata')
         t.lexer.lineno += t.value.count('\n')
@@ -1214,7 +1215,7 @@ class IDLParser(object):
 
     def p_interface(self, p):
         """interface : attributes INTERFACE IDENTIFIER ifacebase ifacebody ';'"""
-        atts, INTERFACE, name, base, body, SEMI = p[1:]
+        atts, INTERFACE, name, base, body, SEMI = p[1], p[2], p[3], p[4], p[5], p[6]
         attlist = atts['attlist']
         doccomments = []
         if 'doccomments' in atts:
@@ -1428,6 +1429,7 @@ class IDLParser(object):
         self.lexer = lex.lex(object=self,
                              outputdir=outputdir,
                              lextab='xpidllex',
+                             reflags=re.DOTALL,
                              optimize=1)
         self.parser = yacc.yacc(module=self,
                                 outputdir=outputdir,
@@ -1461,5 +1463,5 @@ class IDLParser(object):
 if __name__ == '__main__':
     p = IDLParser()
     for f in sys.argv[1:]:
-        print "Parsing %s" % f
+        print("Parsing %s" % f)
         p.parse(open(f).read(), filename=f)
diff --git a/xpcom/typelib/xpt/tools/runtests.py b/xpcom/typelib/xpt/tools/runtests.py
index a86e6625df..7dcb1f1a1f 100644
--- a/xpcom/typelib/xpt/tools/runtests.py
+++ b/xpcom/typelib/xpt/tools/runtests.py
@@ -30,6 +30,7 @@
 # official policies, either expressed or implied, of the Mozilla
 # Foundation.
 
+from __future__ import print_function
 import difflib
 import os
 from StringIO import StringIO
@@ -66,9 +67,9 @@ if "MOZILLA_OBJDIR" in os.environ:
                 # now run xpt_dump on it
                 out2 = get_output(xptdump, fullpath)
                 if out != out2:
-                    print "diff %s" % f
+                    print("diff %s" % f)
                     for line in difflib.unified_diff(out2.split("\n"), out.split("\n"), lineterm=""):
-                        print line
+                        print(line)
                 self.assert_(out == out2, "xpt_dump output should be identical for %s" % f)
 
 
diff --git a/xpcom/typelib/xpt/tools/xpt.py b/xpcom/typelib/xpt/tools/xpt.py
index 67d40f7b2d..99a5a566b3 100755
--- a/xpcom/typelib/xpt/tools/xpt.py
+++ b/xpcom/typelib/xpt/tools/xpt.py
@@ -66,13 +66,18 @@ InterfaceType()        - construct a new object representing a type that
 """
 
 from __future__ import with_statement
+from __future__ import print_function
 import os
 import sys
 import struct
 import operator
 
+# Python 3: cmp() builtin was removed
+def cmp(a, b):
+    return (a > b) - (a < b)
+
 # header magic
-XPT_MAGIC = "XPCOM\nTypeLib\r\n\x1a"
+XPT_MAGIC = b"XPCOM\nTypeLib\r\n\x1a"
 TYPELIB_VERSION = (1, 2)
 
 
@@ -94,9 +99,7 @@ def M_add_class_attribs(attribs):
 
 
 def enum(*names):
-    class Foo(object):
-        __metaclass__ = M_add_class_attribs(enumerate(names))
-
+    class Foo(object, metaclass=M_add_class_attribs(enumerate(names))):
         def __setattr__(self, name, value):  # this makes it read-only
             raise NotImplementedError
     return Foo()
@@ -158,11 +161,20 @@ class Type(object):
     def __cmp__(self, other):
         return (
             # First make sure we have two Types of the same type (no pun intended!)
-            cmp(type(self), type(other)) or
+            cmp(type(self).__name__, type(other).__name__) or
             cmp(self.pointer, other.pointer) or
             cmp(self.reference, other.reference)
         )
 
+    def __lt__(self, other):
+        return self.__cmp__(other) < 0
+
+    def __eq__(self, other):
+        return self.__cmp__(other) == 0
+
+    def __hash__(self):
+        return hash((type(self).__name__, self.pointer, self.reference))
+
     @staticmethod
     def decodeflags(byte):
         """
@@ -249,6 +261,10 @@ class SimpleType(Type):
             cmp(self.tag, other.tag)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    __hash__ = Type.__hash__
+
     @staticmethod
     def get(data, tag, flags):
         """
@@ -303,6 +319,10 @@ class InterfaceType(Type):
             cmp(self.tag, other.tag)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    __hash__ = Type.__hash__
+
     @staticmethod
     def read(typelib, map, data_pool, offset, flags):
         """
@@ -364,6 +384,10 @@ class InterfaceIsType(Type):
             cmp(self.tag, other.tag)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    __hash__ = Type.__hash__
+
     @staticmethod
     def read(typelib, map, data_pool, offset, flags):
         """
@@ -425,6 +449,10 @@ class ArrayType(Type):
             cmp(self.tag, other.tag)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    __hash__ = Type.__hash__
+
     @staticmethod
     def read(typelib, map, data_pool, offset, flags):
         """
@@ -483,6 +511,10 @@ class StringWithSizeType(Type):
             cmp(self.tag, other.tag)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    __hash__ = Type.__hash__
+
     @staticmethod
     def read(typelib, map, data_pool, offset, flags):
         """
@@ -539,6 +571,10 @@ class WideStringWithSizeType(Type):
             cmp(self.tag, other.tag)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    __hash__ = Type.__hash__
+
     @staticmethod
     def read(typelib, map, data_pool, offset, flags):
         """
@@ -604,6 +640,10 @@ class Param(object):
             cmp(self.optional, other.optional)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    def __hash__(self): return id(self)
+
     @staticmethod
     def decodeflags(byte):
         """
@@ -740,6 +780,10 @@ class Method(object):
             cmp(self.result, other.result)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    def __hash__(self): return id(self)
+
     def read_params(self, typelib, map, data_pool, offset, num_args):
         """
         Read |num_args| ParamDescriptors representing this Method's arguments
@@ -851,7 +895,7 @@ class Method(object):
         """
         if self.name:
             self._name_offset = file.tell() - data_pool_offset + 1
-            file.write(self.name + "\x00")
+            file.write(self.name.encode('utf-8') + b"\x00")
         else:
             self._name_offset = 0
 
@@ -884,6 +928,10 @@ class Constant(object):
             cmp(self.value, other.value)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    def __hash__(self): return id(self)
+
     @staticmethod
     def read(typelib, map, data_pool, offset):
         """
@@ -928,7 +976,7 @@ class Constant(object):
         """
         if self.name:
             self._name_offset = file.tell() - data_pool_offset + 1
-            file.write(self.name + "\x00")
+            file.write(self.name.encode('utf-8') + b"\x00")
         else:
             self._name_offset = 0
 
@@ -1026,6 +1074,10 @@ class Interface(object):
             cmp(self.main_process_scriptable_only, other.main_process_scriptable_only)
         )
 
+    def __lt__(self, other): return self.__cmp__(other) < 0
+    def __eq__(self, other): return self.__cmp__(other) == 0
+    # __hash__ already defined above
+
     def read_descriptor(self, typelib, map, data_pool):
         offset = self._descriptor_offset
         if offset == 0:
@@ -1114,12 +1166,12 @@ class Interface(object):
         """
         if self.name:
             self._name_offset = file.tell() - data_pool_offset + 1
-            file.write(self.name + "\x00")
+            file.write(self.name.encode('utf-8') + b"\x00")
         else:
             self._name_offset = 0
         if self.namespace:
             self._namespace_offset = file.tell() - data_pool_offset + 1
-            file.write(self.namespace + "\x00")
+            file.write(self.namespace.encode('utf-8') + b"\x00")
         else:
             self._namespace_offset = 0
         for m in self.methods:
@@ -1157,7 +1209,7 @@ class Typelib(object):
 
         """
         def hexify(s):
-            return ''.join(["%02x" % ord(x) for x in s])
+            return ''.join(["%02x" % (x if isinstance(x, int) else ord(x)) for x in s])
 
         return "%s-%s-%s-%s-%s" % (hexify(iid[:4]), hexify(iid[4:6]),
                                    hexify(iid[6:8]), hexify(iid[8:10]),
@@ -1170,16 +1222,19 @@ class Typelib(object):
 
         """
         s = iid_str.replace('-', '')
-        return ''.join([chr(int(s[i:i+2], 16)) for i in range(0, len(s), 2)])
+        return bytes([int(s[i:i+2], 16) for i in range(0, len(s), 2)])
 
     @staticmethod
     def read_string(map, data_pool, offset):
         if offset == 0:
             return ""
-        sz = map.find('\x00', data_pool + offset - 1)
+        sz = map.find(b'\x00', data_pool + offset - 1)
         if sz == -1:
             return ""
-        return map[data_pool + offset - 1:sz]
+        result = map[data_pool + offset - 1:sz]
+        if isinstance(result, bytes):
+            result = result.decode('utf-8', 'replace')
+        return result
 
     @staticmethod
     def read(input_file):
@@ -1192,7 +1247,7 @@ class Typelib(object):
         filename = ""
         data = None
         expected_size = None
-        if isinstance(input_file, basestring):
+        if isinstance(input_file, str):
             filename = input_file
             with open(input_file, "rb") as f:
                 st = os.fstat(f.fileno())
@@ -1272,11 +1327,11 @@ class Typelib(object):
         headersize = (Typelib._header.size + 1)
         if headersize % 4:
             headersize += 4 - headersize % 4
-        fd.write("\x00" * headersize)
+        fd.write(b"\x00" * headersize)
         # save this offset, it's the interface directory offset.
         interface_directory_offset = fd.tell()
         # write out space for an interface directory
-        fd.write("\x00" * Interface._direntry.size * len(self.interfaces))
+        fd.write(b"\x00" * Interface._direntry.size * len(self.interfaces))
         # save this offset, it's the data pool offset.
         data_pool_offset = fd.tell()
         # write out all the interface descriptors to the data pool
@@ -1309,7 +1364,7 @@ class Typelib(object):
 
         """
         self._sanityCheck()
-        if isinstance(output_file, basestring):
+        if isinstance(output_file, str):
             with open(output_file, "wb") as f:
                 self.writefd(f)
         else:
@@ -1392,7 +1447,7 @@ def xpt_link(inputs):
         return Typelib.read(i)
 
     if not inputs:
-        print >>sys.stderr, "Usage: xpt_link  "
+        print("Usage: xpt_link  ", file=sys.stderr)
         return None
     # This is the aggregate list of interfaces.
     interfaces = []
@@ -1532,7 +1587,7 @@ def xpt_link(inputs):
 
 if __name__ == '__main__':
     if len(sys.argv) < 3:
-        print >>sys.stderr, "xpt  "
+        print("xpt  ", file=sys.stderr)
         sys.exit(1)
     if sys.argv[1] == 'dump':
         xpt_dump(sys.argv[2])
diff --git a/xulrunner/app/install_app.py b/xulrunner/app/install_app.py
index 6be8c5ecb5..d7707f2426 100644
--- a/xulrunner/app/install_app.py
+++ b/xulrunner/app/install_app.py
@@ -5,12 +5,13 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Min version of python is 2.7
+from __future__ import print_function
 import sys
 if ((sys.version_info.major != 2) or (sys.version_info.minor < 7)):
     raise Exception("You need to use Python version 2.7 or higher")
 
 import os, shutil, re, zipfile
-from ConfigParser import SafeConfigParser
+from configparser import SafeConfigParser
 
 # Platform-specific support
 # see https://developer.mozilla.org/en/XULRunner/Deploying_XULRunner_1.8
@@ -215,7 +216,7 @@ def handleCommandLine():
     except exn:
         shutil.rmtree(cmds.installDir)
         raise exn
-    print cmds.appName + " application installed to " + cmds.installDir
+    print(cmds.appName + " application installed to " + cmds.installDir)
 
 if __name__ == '__main__':
     handleCommandLine()