Bug 1408365 - Enable flake8/py2/py3 linters on python/mozboot. r?ahal draft
authorSteve Armand <stevea1@mac.com>
Fri, 13 Oct 2017 23:33:00 -0400
changeset 680415 f1abc0c0dcf5789b0dad06c7fd30645c33192e7b
parent 680263 56b5c1a87dcb2c0391e7f642f99e6638dcf235c0
child 735857 4f99eb37e82925bec6a563c9e9b77ee2d67b09db
push id84506
push userbmo:stevea1@mac.com
push dateSat, 14 Oct 2017 03:36:03 +0000
reviewersahal
bugs1408365
milestone58.0a1
Bug 1408365 - Enable flake8/py2/py3 linters on python/mozboot. r?ahal MozReview-Commit-ID: 3koZq509bjP
python/mozboot/bin/bootstrap.py
python/mozboot/mozboot/android.py
python/mozboot/mozboot/archlinux.py
python/mozboot/mozboot/base.py
python/mozboot/mozboot/bootstrap.py
python/mozboot/mozboot/centosfedora.py
python/mozboot/mozboot/debian.py
python/mozboot/mozboot/freebsd.py
python/mozboot/mozboot/gentoo.py
python/mozboot/mozboot/linux_common.py
python/mozboot/mozboot/mach_commands.py
python/mozboot/mozboot/mozillabuild.py
python/mozboot/mozboot/openbsd.py
python/mozboot/mozboot/osx.py
python/mozboot/mozboot/rust.py
python/mozboot/mozboot/stylo.py
python/mozboot/mozboot/util.py
python/mozboot/mozboot/windows.py
python/mozboot/setup.py
tools/lint/flake8.yml
tools/lint/py2.yml
--- a/python/mozboot/bin/bootstrap.py
+++ b/python/mozboot/bin/bootstrap.py
@@ -8,22 +8,24 @@
 #
 # The role of this script is to load the Python modules containing actual
 # bootstrap support. It does this through various means, including fetching
 # content from the upstream source repository.
 
 # If we add unicode_literals, optparse breaks on Python 2.6.1 (which is needed
 # to support OS X 10.6).
 
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
 WRONG_PYTHON_VERSION_MESSAGE = '''
-Bootstrap currently only runs on Python 2.7 or Python 2.6. Please try re-running with python2.7 or python2.6.
+Bootstrap currently only runs on Python 2.7 or Python 2.6.
+Please try re-running with python2.7 or python2.6.
 
-If these aren't available on your system, you may need to install them. Look for a "python2" or "python27" package in your package manager.
+If these aren't available on your system, you may need to install them.
+Look for a "python2" or "python27" package in your package manager.
 '''
 
 import sys
 if sys.version_info[:2] not in [(2, 6), (2, 7)]:
     print(WRONG_PYTHON_VERSION_MESSAGE)
     sys.exit(1)
 
 import os
--- a/python/mozboot/mozboot/android.py
+++ b/python/mozboot/mozboot/android.py
@@ -1,14 +1,14 @@
 # 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/.
 
 # If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
 import errno
 import os
 import stat
 import subprocess
 import sys
 
 ANDROID_NDK_EXISTS = '''
@@ -183,27 +183,28 @@ def ensure_android(os_name, artifact_mod
             'android-sdk-license': '8933bad161af4178b1185d1a37fbf41ea5269c55',
             'android-sdk-preview-license': '84831b9409646a918e30573bab4c9c91346d8abd',
         }
         for license, tag in licenses.items():
             lname = os.path.join(path, license)
             if not os.path.isfile(lname):
                 open(lname, 'w').write('\n{0}\n'.format(tag))
 
-
     # We expect the |sdkmanager| tool to be at
     # ~/.mozbuild/android-sdk-$OS_NAME/tools/bin/sdkmanager.
     sdkmanager_tool = os.path.join(sdk_path, 'tools', 'bin', 'sdkmanager')
     ensure_android_packages(sdkmanager_tool=sdkmanager_tool)
 
 
-def ensure_android_sdk_and_ndk(mozbuild_path, os_name, sdk_path, sdk_url, ndk_path, ndk_url, artifact_mode):
+def ensure_android_sdk_and_ndk(mozbuild_path, os_name, sdk_path, sdk_url, ndk_path, ndk_url,
+                               artifact_mode):
     '''
     Ensure the Android SDK and NDK are found at the given paths.  If not, fetch
-    and unpack the SDK and/or NDK from the given URLs into |mozbuild_path/{android-sdk-$OS_NAME,android-ndk-$VER}|.
+    and unpack the SDK and/or NDK from the given URLs into
+    |mozbuild_path/{android-sdk-$OS_NAME,android-ndk-$VER}|.
     '''
 
     # It's not particularly bad to overwrite the NDK toolchain, but it does take
     # a while to unpack, so let's avoid the disk activity if possible.  The SDK
     # may prompt about licensing, so we do this first.
     # Check for Android NDK only if we are not in artifact mode.
     if not artifact_mode:
         if os.path.isdir(ndk_path):
@@ -220,28 +221,30 @@ def ensure_android_sdk_and_ndk(mozbuild_
         print(ANDROID_SDK_EXISTS % sdk_path)
     elif os.path.isdir(sdk_path):
         raise NotImplementedError(ANDROID_SDK_TOO_OLD % sdk_path)
     else:
         # The SDK archive used to include a top-level
         # android-sdk-$OS_NAME directory; it no longer does so.  We
         # preserve the old convention to smooth detecting existing SDK
         # installations.
-        install_mobile_android_sdk_or_ndk(sdk_url, os.path.join(mozbuild_path, 'android-sdk-{0}'.format(os_name)))
+        install_mobile_android_sdk_or_ndk(sdk_url, os.path.join(mozbuild_path,
+                                          'android-sdk-{0}'.format(os_name)))
 
 
 def ensure_android_packages(sdkmanager_tool, packages=None):
     '''
     Use the given sdkmanager tool (like 'sdkmanager') to install required
     Android packages.
     '''
 
     # This tries to install all the required Android packages.  The user
     # may be prompted to agree to the Android license.
-    package_file_name = os.path.abspath(os.path.join(os.path.dirname(__file__), 'android-packages.txt'))
+    package_file_name = os.path.abspath(os.path.join(os.path.dirname(__file__),
+                                        'android-packages.txt'))
     print(INSTALLING_ANDROID_PACKAGES % open(package_file_name, 'rt').read())
     subprocess.check_call([sdkmanager_tool,
                            '--package_file={0}'.format(package_file_name)])
 
 
 def suggest_mozconfig(os_name, artifact_mode=False):
     _mozbuild_path, sdk_path, ndk_path = get_paths(os_name)
     if artifact_mode:
@@ -263,17 +266,17 @@ def android_ndk_url(os_name, ver='r11c')
         arch = 'x86_64'
     else:
         arch = 'x86'
 
     return '%s-%s-%s-%s.zip' % (base_url, ver, os_name, arch)
 
 
 def main(argv):
-    import optparse # No argparse, which is new in Python 2.7.
+    import optparse  # No argparse, which is new in Python 2.7.
     import platform
 
     parser = optparse.OptionParser()
     parser.add_option('-a', '--artifact-mode', dest='artifact_mode', action='store_true',
                       help='If true, install only the Android SDK (and not the Android NDK).')
     parser.add_option('--no-interactive', dest='no_interactive', action='store_true',
                       help='Accept the Android SDK licenses without user interaction.')
 
@@ -282,19 +285,20 @@ def main(argv):
     os_name = None
     if platform.system() == 'Darwin':
         os_name = 'macosx'
     elif platform.system() == 'Linux':
         os_name = 'linux'
     elif platform.system() == 'Windows':
         os_name = 'windows'
     else:
-        raise NotImplementedError("We don't support bootstrapping the Android SDK (or Android NDK) "
-                                  "on {0} yet!".format(platform.system()))
+        raise NotImplementedError("We don't support bootstrapping the Android SDK (or Android "
+                                  "NDK) on {0} yet!".format(platform.system()))
 
-    ensure_android(os_name, artifact_mode=options.artifact_mode, no_interactive=options.no_interactive)
+    ensure_android(os_name, artifact_mode=options.artifact_mode,
+                   no_interactive=options.no_interactive)
     suggest_mozconfig(os_name, options.artifact_mode)
 
     return 0
 
 
 if __name__ == '__main__':
     sys.exit(main(sys.argv))
--- a/python/mozboot/mozboot/archlinux.py
+++ b/python/mozboot/mozboot/archlinux.py
@@ -1,12 +1,14 @@
 # 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 absolute_import, print_function
+
 import os
 import sys
 import tempfile
 import subprocess
 import glob
 
 from mozboot.base import BaseBootstrapper
 from mozboot.linux_common import StyloInstall
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -1,15 +1,14 @@
 # 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, unicode_literals
+from __future__ import absolute_import, print_function, unicode_literals
 
-import errno
 import hashlib
 import os
 import re
 import subprocess
 import sys
 import urllib2
 
 from distutils.version import LooseVersion
@@ -148,16 +147,17 @@ ac_add_options --enable-artifact-builds
 MODERN_MERCURIAL_VERSION = LooseVersion('3.7.3')
 
 # Upgrade Python older than this.
 MODERN_PYTHON_VERSION = LooseVersion('2.7.3')
 
 # Upgrade rust older than this.
 MODERN_RUST_VERSION = LooseVersion('1.19.0')
 
+
 class BaseBootstrapper(object):
     """Base class for system bootstrappers."""
 
     def __init__(self, no_interactive=False):
         self.package_manager_updated = False
         self.no_interactive = no_interactive
         self.state_dir = None
 
@@ -545,27 +545,25 @@ class BaseBootstrapper(object):
         print(PYTHON_UNABLE_UPGRADE % (current, MODERN_PYTHON_VERSION))
 
     def is_rust_modern(self):
         rustc = self.which('rustc')
         if not rustc:
             print('Could not find a Rust compiler.')
             return False, None
 
-        cargo = self.which('cargo')
-
         our = self._parse_version(rustc)
         if not our:
             return False, None
 
         return our >= MODERN_RUST_VERSION, our
 
     def cargo_home(self):
         cargo_home = os.environ.get('CARGO_HOME',
-                os.path.expanduser(os.path.join('~', '.cargo')))
+                                    os.path.expanduser(os.path.join('~', '.cargo')))
         cargo_bin = os.path.join(cargo_home, 'bin')
         return cargo_home, cargo_bin
 
     def win_to_msys_path(self, path):
         '''Convert a windows-style path to msys style.'''
         drive, path = os.path.splitdrive(path)
         path = '/'.join(path.split('\\'))
         if drive:
@@ -604,17 +602,17 @@ class BaseBootstrapper(object):
             # Rust wasn't in PATH. Check the standard location.
             cargo_home, cargo_bin = self.cargo_home()
             try_rustc = os.path.join(cargo_bin, 'rustc' + rust.exe_suffix())
             try_cargo = os.path.join(cargo_bin, 'cargo' + rust.exe_suffix())
             have_rustc = os.path.exists(try_rustc)
             have_cargo = os.path.exists(try_cargo)
             if have_rustc or have_cargo:
                 self.print_rust_path_advice(RUST_NOT_IN_PATH,
-                        cargo_home, cargo_bin)
+                                            cargo_home, cargo_bin)
                 sys.exit(1)
         else:
             print('Your version of Rust (%s) is too old.' % version)
 
         rustup = self.which('rustup')
         if rustup:
             rustup_version = self._parse_version(rustup)
             if not rustup_version:
@@ -629,25 +627,25 @@ class BaseBootstrapper(object):
                 sys.exit(1)
         else:
             # No rustup. Download and run the installer.
             print('Will try to install Rust.')
             self.install_rust()
 
     def ensure_rust_targets(self, rustup):
         """Make sure appropriate cross target libraries are installed."""
-        target_list =  subprocess.check_output([rustup, 'target', 'list'])
+        target_list = subprocess.check_output([rustup, 'target', 'list'])
         targets = [line.split()[0] for line in target_list.splitlines()
-                if 'installed' in line or 'default' in line]
+                   if 'installed' in line or 'default' in line]
         print('Rust supports %s targets.' % ', '.join(targets))
 
         # Support 32-bit Windows on 64-bit Windows.
         win32 = 'i686-pc-windows-msvc'
         win64 = 'x86_64-pc-windows-msvc'
-        if rust.platform() == win64 and not win32 in targets:
+        if rust.platform() == win64 and win32 not in targets:
             subprocess.check_call([rustup, 'target', 'add', win32])
 
     def upgrade_rust(self, rustup):
         """Upgrade Rust.
 
         Invoke rustup from the given path to update the rust install."""
         subprocess.check_call([rustup, 'update'])
 
@@ -667,22 +665,22 @@ class BaseBootstrapper(object):
         os.close(fd)
         try:
             self.http_download_and_save(url, rustup_init, checksum)
             mode = os.stat(rustup_init).st_mode
             os.chmod(rustup_init, mode | stat.S_IRWXU)
             print('Ok')
             print('Running rustup-init...')
             subprocess.check_call([rustup_init, '-y',
-                '--default-toolchain', 'stable',
-                '--default-host', platform,
-            ])
+                                   '--default-toolchain', 'stable',
+                                   '--default-host', platform, ]
+                                  )
             cargo_home, cargo_bin = self.cargo_home()
             self.print_rust_path_advice(RUST_INSTALL_COMPLETE,
-                    cargo_home, cargo_bin)
+                                        cargo_home, cargo_bin)
         finally:
             try:
                 os.remove(rustup_init)
             except OSError as e:
                 if e.errno != errno.ENOENT:
                     raise
 
     def http_download_and_save(self, url, dest, hexhash, digest='sha256'):
--- a/python/mozboot/mozboot/bootstrap.py
+++ b/python/mozboot/mozboot/bootstrap.py
@@ -1,14 +1,14 @@
 # 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/.
 
 # If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
 import platform
 import sys
 import os
 import subprocess
 
 # Don't forgot to add new mozboot modules to the bootstrap download
 # list in bin/bootstrap.py!
@@ -52,17 +52,17 @@ But don't worry! You can always switch c
 
 You can learn more about Artifact mode builds at
 https://developer.mozilla.org/en-US/docs/Artifact_builds.
 
 Please choose the version of Firefox you want to build:
 %s
 Your choice: '''
 
-APPLICATIONS_LIST=[
+APPLICATIONS_LIST = [
     ('Firefox for Desktop Artifact Mode', 'browser_artifact_mode'),
     ('Firefox for Desktop', 'browser'),
     ('Firefox for Android Artifact Mode', 'mobile_android_artifact_mode'),
     ('Firefox for Android', 'mobile_android'),
 ]
 
 # This is a workaround for the fact that we must support python2.6 (which has
 # no OrderedDict)
@@ -264,33 +264,34 @@ class Bootstrapper(object):
             if os.listdir(dest) == []:
                 return dest
 
             newdest = os.path.join(dest, 'mozilla-unified')
             if os.path.exists(newdest):
                 print(CLONE_MERCURIAL_NOT_EMPTY_FALLBACK_FAILED.format(dest))
                 continue
 
-            choice = self.instance.prompt_int(prompt=CLONE_MERCURIAL_NOT_EMPTY.format(dest, newdest),
-                                              low=1, high=3)
+            choice = self.instance.prompt_int(prompt=CLONE_MERCURIAL_NOT_EMPTY.format(dest,
+                                              newdest), low=1, high=3)
             if choice == 1:
                 return newdest
             if choice == 2:
                 continue
             return ''
 
     def bootstrap(self):
         if self.choice is None:
             # Like ['1. Firefox for Desktop', '2. Firefox for Android Artifact Mode', ...].
             labels = ['%s. %s' % (i + 1, name) for (i, (name, _)) in enumerate(APPLICATIONS_LIST)]
             prompt = APPLICATION_CHOICE % '\n'.join(labels)
             prompt_choice = self.instance.prompt_int(prompt=prompt, low=1, high=len(APPLICATIONS))
             name, application = APPLICATIONS_LIST[prompt_choice-1]
         elif self.choice not in APPLICATIONS.keys():
-            raise Exception('Please pick a valid application choice: (%s)' % '/'.join(APPLICATIONS.keys()))
+            raise Exception('Please pick a valid application choice: (%s)' %
+                            '/'.join(APPLICATIONS.keys()))
         else:
             name, application = APPLICATIONS[self.choice]
 
         self.instance.install_system_packages()
 
         # Like 'install_browser_packages' or 'install_mobile_android_packages'.
         getattr(self.instance, 'install_%s_packages' % application)()
 
@@ -366,17 +367,18 @@ class Bootstrapper(object):
             if not have_clone:
                 print(STYLO_REQUIRES_CLONE)
                 sys.exit(1)
 
             self.instance.state_dir = state_dir
             self.instance.ensure_stylo_packages(state_dir, checkout_root)
 
         print(self.finished % name)
-        if not (self.instance.which('rustc') and self.instance._parse_version('rustc') >= MODERN_RUST_VERSION):
+        if not (self.instance.which('rustc') and self.instance._parse_version('rustc')
+                >= MODERN_RUST_VERSION):
             print("To build %s, please restart the shell (Start a new terminal window)" % name)
 
         # Like 'suggest_browser_mozconfig' or 'suggest_mobile_android_mozconfig'.
         getattr(self.instance, 'suggest_%s_mozconfig' % application)()
 
 
 def update_vct(hg, root_state_dir):
     """Ensure version-control-tools in the state directory is up to date."""
@@ -480,17 +482,18 @@ def clone_firefox(hg, dest):
         # to bound revlog read time.
         fh.write('[format]\n')
         fh.write('# This is necessary to keep performance in check\n')
         fh.write('maxchainlen = 10000\n')
 
     res = subprocess.call([hg, 'pull', 'https://hg.mozilla.org/mozilla-unified'], cwd=dest)
     print('')
     if res:
-        print('error pulling; try running `hg pull https://hg.mozilla.org/mozilla-unified` manually')
+        print('error pulling; try running `hg pull https://hg.mozilla.org/mozilla-unified` '
+              'manually')
         return False
 
     print('updating to "central" - the development head of Gecko and Firefox')
     res = subprocess.call([hg, 'update', '-r', 'central'], cwd=dest)
     if res:
         print('error updating; you will need to `hg update` manually')
 
     print('Firefox source code available at %s' % dest)
--- a/python/mozboot/mozboot/centosfedora.py
+++ b/python/mozboot/mozboot/centosfedora.py
@@ -1,12 +1,14 @@
 # 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 absolute_import
+
 import platform
 
 from mozboot.base import BaseBootstrapper
 from mozboot.linux_common import StyloInstall
 
 
 class CentOSFedoraBootstrapper(StyloInstall, BaseBootstrapper):
     def __init__(self, distro, version, dist_id, **kwargs):
--- a/python/mozboot/mozboot/debian.py
+++ b/python/mozboot/mozboot/debian.py
@@ -1,12 +1,14 @@
 # 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 absolute_import, print_function
+
 from mozboot.base import BaseBootstrapper
 from mozboot.linux_common import StyloInstall
 
 
 MERCURIAL_INSTALL_PROMPT = '''
 Mercurial releases a new version every 3 months and your distro's package
 may become out of date. This may cause incompatibility with some
 Mercurial extensions that rely on new Mercurial features. As a result,
@@ -84,17 +86,17 @@ class DebianBootstrapper(StyloInstall, B
         BaseBootstrapper.__init__(self, **kwargs)
 
         self.version = version
         self.dist_id = dist_id
 
         self.packages = self.COMMON_PACKAGES + self.DISTRO_PACKAGES
         self.browser_packages = self.BROWSER_COMMON_PACKAGES + self.BROWSER_DISTRO_PACKAGES
         self.mobile_android_packages = self.MOBILE_ANDROID_COMMON_PACKAGES + \
-                                       self.MOBILE_ANDROID_DISTRO_PACKAGES
+            self.MOBILE_ANDROID_DISTRO_PACKAGES
 
     def install_system_packages(self):
         self.apt_install(*self.packages)
 
     def install_browser_packages(self):
         self.ensure_browser_packages()
 
     def install_browser_artifact_mode_packages(self):
--- a/python/mozboot/mozboot/freebsd.py
+++ b/python/mozboot/mozboot/freebsd.py
@@ -1,14 +1,17 @@
 # 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 absolute_import
+
 from mozboot.base import BaseBootstrapper
 
+
 class FreeBSDBootstrapper(BaseBootstrapper):
     def __init__(self, version, flavor, **kwargs):
         BaseBootstrapper.__init__(self, **kwargs)
         self.version = int(version.split('.')[0])
         self.flavor = flavor.lower()
 
         self.packages = [
             'autoconf213',
--- a/python/mozboot/mozboot/gentoo.py
+++ b/python/mozboot/mozboot/gentoo.py
@@ -1,12 +1,14 @@
 # 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 absolute_import
+
 from mozboot.base import BaseBootstrapper
 from mozboot.linux_common import StyloInstall
 
 
 class GentooBootstrapper(StyloInstall, BaseBootstrapper):
     def __init__(self, version, dist_id, **kwargs):
         BaseBootstrapper.__init__(self, **kwargs)
 
@@ -45,17 +47,17 @@ class GentooBootstrapper(StyloInstall, B
         emerge_info = subprocess.check_output(['emerge', '--info'])
         distdir_re = re.compile('^DISTDIR="(.*)"$', re.MULTILINE)
         distdir = distdir_re.search(emerge_info).group(1)
 
         # Fetch the Oracle JDK since portage can't fetch it on its own
         jdk_file = 'jdk-8u144-linux-x64.tar.gz'
         self.run_as_root(['wget', '-c', '-O', distdir + '/' + jdk_file,
                           '--header', 'Cookie: oraclelicense=accept-securebackup-cookie',
-                          'http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/' + jdk_file])
+                          'http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/' + jdk_file])  # noqa
 
         # Install the Oracle JDK. We explicitly prompt the user to accept the
         # changes because this command might need to modify the portage
         # configuration files and doing so without user supervision is dangerous
         self.run_as_root(['emerge', '--noreplace', '--quiet',
                           '--autounmask-continue', '--ask',
                           '=dev-java/oracle-jdk-bin-1.8.0.144'])
 
--- a/python/mozboot/mozboot/linux_common.py
+++ b/python/mozboot/mozboot/linux_common.py
@@ -1,14 +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/.
 
 # An easy way for distribution-specific bootstrappers to share the code
 # needed to install Stylo dependencies.  This class must come before
 # BaseBootstrapper in the inheritance list.
+
+from __future__ import absolute_import
+
+
 class StyloInstall(object):
     def __init__(self, **kwargs):
         pass
 
     def ensure_stylo_packages(self, state_dir, checkout_root):
         import stylo
         self.install_tooltool_clang_package(state_dir, checkout_root, stylo.LINUX)
--- a/python/mozboot/mozboot/mach_commands.py
+++ b/python/mozboot/mozboot/mach_commands.py
@@ -33,19 +33,19 @@ class Bootstrap(object):
 
 
 @CommandProvider
 class VersionControlCommands(object):
     def __init__(self, context):
         self._context = context
 
     @Command('mercurial-setup', category='devenv',
-        description='Help configure Mercurial for optimal development.')
+             description='Help configure Mercurial for optimal development.')
     @CommandArgument('-u', '--update-only', action='store_true',
-        help='Only update recommended extensions, don\'t run the wizard.')
+                     help='Only update recommended extensions, don\'t run the wizard.')
     def mercurial_setup(self, update_only=False):
         """Ensure Mercurial is optimally configured.
 
         This command will inspect your Mercurial configuration and
         guide you through an interactive wizard helping you configure
         Mercurial for optimal use on Mozilla projects.
 
         User choice is respected: no changes are made without explicit
--- a/python/mozboot/mozboot/mozillabuild.py
+++ b/python/mozboot/mozboot/mozillabuild.py
@@ -1,20 +1,21 @@
 # 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/.
 
-import errno
+from __future__ import absolute_import, print_function
+
 import os
 import sys
 import subprocess
-import tempfile
 
 from mozboot.base import BaseBootstrapper
 
+
 class MozillaBuildBootstrapper(BaseBootstrapper):
     '''Bootstrapper for MozillaBuild to install rustup.'''
     def __init__(self, no_interactive=False):
         BaseBootstrapper.__init__(self, no_interactive=no_interactive)
         print("mach bootstrap is not fully implemented in MozillaBuild")
 
     def which(self, name):
         return BaseBootstrapper.which(self, name + '.exe')
@@ -53,9 +54,8 @@ class MozillaBuildBootstrapper(BaseBoots
     def run(self, command):
         subprocess.check_call(command, stdin=sys.stdin)
 
     def pip_install(self, *packages):
         pip_dir = os.path.join(os.environ['MOZILLABUILD'], 'python', 'Scripts', 'pip.exe')
         command = [pip_dir, 'install', '--upgrade']
         command.extend(packages)
         self.run(command)
-
--- a/python/mozboot/mozboot/openbsd.py
+++ b/python/mozboot/mozboot/openbsd.py
@@ -1,12 +1,14 @@
 # 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 absolute_import
+
 from mozboot.base import BaseBootstrapper
 
 
 class OpenBSDBootstrapper(BaseBootstrapper):
     def __init__(self, version, **kwargs):
         BaseBootstrapper.__init__(self, **kwargs)
 
         self.packages = [
--- a/python/mozboot/mozboot/osx.py
+++ b/python/mozboot/mozboot/osx.py
@@ -1,13 +1,13 @@
 # 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, unicode_literals
+from __future__ import absolute_import, print_function, unicode_literals
 
 import os
 import re
 import subprocess
 import sys
 import tempfile
 try:
     from urllib2 import urlopen
@@ -15,24 +15,26 @@ except ImportError:
     from urllib.request import urlopen
 
 from distutils.version import StrictVersion
 
 from mozboot.base import BaseBootstrapper
 
 HOMEBREW_BOOTSTRAP = 'https://raw.githubusercontent.com/Homebrew/install/master/install'
 XCODE_APP_STORE = 'macappstore://itunes.apple.com/app/id497799835?mt=12'
-XCODE_LEGACY = 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_3.2.6_and_ios_sdk_4.3__final/xcode_3.2.6_and_ios_sdk_4.3.dmg'
+XCODE_LEGACY = ('https://developer.apple.com/downloads/download.action?path=Developer_Tools/'
+                'xcode_3.2.6_and_ios_sdk_4.3__final/xcode_3.2.6_and_ios_sdk_4.3.dmg')
 
-MACPORTS_URL = {'11': 'https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.11-ElCapitan.pkg',
-                '10': 'https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.10-Yosemite.pkg',
-                '9': 'https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.9-Mavericks.pkg',
-                '8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.8-MountainLion.pkg',
-                '7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.7-Lion.pkg',
-                '6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.6-SnowLeopard.pkg', }
+MACPORTS = 'https://distfiles.macports.org/MacPorts/'
+MACPORTS_URL = {'11': MACPORTS+'MacPorts-2.3.4-10.11-ElCapitan.pkg',
+                '10': MACPORTS+'MacPorts-2.3.4-10.10-Yosemite.pkg',
+                '9': MACPORTS+'MacPorts-2.3.4-10.9-Mavericks.pkg',
+                '8': MACPORTS+'MacPorts-2.3.4-10.8-MountainLion.pkg',
+                '7': MACPORTS+'MacPorts-2.3.4-10.7-Lion.pkg',
+                '6': MACPORTS+'MacPorts-2.3.4-10.6-SnowLeopard.pkg', }
 
 MACPORTS_CLANG_PACKAGE = 'clang-3.3'
 
 RE_CLANG_VERSION = re.compile('Apple (?:clang|LLVM) version (\d+\.\d+)')
 
 APPLE_CLANG_MINIMUM_VERSION = StrictVersion('4.2')
 
 XCODE_REQUIRED = '''
@@ -191,23 +193,25 @@ class OSXBootstrapper(BaseBootstrapper):
 
     def install_browser_artifact_mode_packages(self):
         getattr(self, 'ensure_%s_browser_packages' % self.package_manager)(artifact_mode=True)
 
     def install_mobile_android_packages(self):
         getattr(self, 'ensure_%s_mobile_android_packages' % self.package_manager)()
 
     def install_mobile_android_artifact_mode_packages(self):
-        getattr(self, 'ensure_%s_mobile_android_packages' % self.package_manager)(artifact_mode=True)
+        getattr(self, 'ensure_%s_mobile_android_packages' %
+                self.package_manager)(artifact_mode=True)
 
     def suggest_mobile_android_mozconfig(self):
         getattr(self, 'suggest_%s_mobile_android_mozconfig' % self.package_manager)()
 
     def suggest_mobile_android_artifact_mode_mozconfig(self):
-        getattr(self, 'suggest_%s_mobile_android_mozconfig' % self.package_manager)(artifact_mode=True)
+        getattr(self, 'suggest_%s_mobile_android_mozconfig' %
+                self.package_manager)(artifact_mode=True)
 
     def ensure_xcode(self):
         if self.os_version < StrictVersion('10.7'):
             if not os.path.exists('/Developer/Applications/Xcode.app'):
                 print(XCODE_REQUIRED_LEGACY)
 
                 subprocess.check_call(['open', XCODE_LEGACY])
                 sys.exit(1)
--- a/python/mozboot/mozboot/rust.py
+++ b/python/mozboot/mozboot/rust.py
@@ -1,19 +1,16 @@
 # 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/.
 
 # If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
-from __future__ import print_function
+from __future__ import absolute_import, print_function
 
-import errno
 import os
-import stat
-import subprocess
 import sys
 
 # Base url for pulling the rustup installer.
 # Use the no-CNAME host for compatibilty with Python 2.7
 # which doesn't support SNI.
 RUSTUP_URL_BASE = 'https://static-rust-lang-org.s3.amazonaws.com/rustup'
 
 # Pull this to get the lastest stable version number.
@@ -36,63 +33,70 @@ RUSTUP_HASHES = {
 
 NO_PLATFORM = '''
 Sorry, we have no installer configured for your platform.
 
 Please try installing rust for your system from https://rustup.rs/
 or from https://rust-lang.org/ or from your package manager.
 '''
 
+
 def rustup_url(host, version=RUSTUP_VERSION):
     '''Download url for a particular version of the installer.'''
     return '%(base)s/archive/%(version)s/%(host)s/rustup-init%(ext)s' % {
                 'base': RUSTUP_URL_BASE,
                 'version': version,
                 'host': host,
                 'ext': exe_suffix(host)}
 
+
 def rustup_hash(host):
     '''Look up the checksum for the given installer.'''
     return RUSTUP_HASHES.get(host, None)
 
+
 def platform():
     '''Determine the appropriate rust platform string for the current host'''
     if sys.platform.startswith('darwin'):
         return 'x86_64-apple-darwin'
     elif sys.platform.startswith(('win32', 'msys')):
         # Bravely assume we'll be building 64-bit Firefox.
         return 'x86_64-pc-windows-msvc'
     elif sys.platform.startswith('linux'):
         return 'x86_64-unknown-linux-gnu'
     elif sys.platform.startswith('freebsd'):
         return 'x86_64-unknown-freebsd'
 
     return None
 
+
 def exe_suffix(host=None):
     if not host:
         host = platform()
     if 'windows' in host:
         return '.exe'
     return ''
 
+
 USAGE = '''
 python rust.py [--update]
 
 Pass the --update option print info for the latest release of rustup-init.
 
 When invoked without the --update option, it queries the latest version
 and verifies the current stored checksums against the distribution server,
 but doesn't update the version installed by `mach bootstrap`.
 '''
 
+
 def unquote(s):
     '''Strip outer quotation marks from a string.'''
     return s.strip("'").strip('"')
 
+
 def rustup_latest_version():
     '''Query the latest version of the rustup installer.'''
     import urllib2
     f = urllib2.urlopen(RUSTUP_MANIFEST)
     # The manifest is toml, but we might not have the toml4 python module
     # available, so use ad-hoc parsing to obtain the current release version.
     #
     # The manifest looks like:
@@ -106,41 +110,44 @@ def rustup_latest_version():
             schema = int(unquote(value))
             if schema != 1:
                 print('ERROR: Unknown manifest schema %s' % value)
                 sys.exit(1)
         elif key == 'version':
             return unquote(value)
     return None
 
+
 def http_download_and_hash(url):
     import hashlib
     import requests
     h = hashlib.sha256()
     r = requests.get(url, stream=True)
     for data in r.iter_content(4096):
         h.update(data)
     return h.hexdigest()
 
+
 def make_checksums(version, validate=False):
     hashes = []
     for platform in RUSTUP_HASHES.keys():
         if validate:
             print('Checking %s... ' % platform, end='')
         else:
             print('Fetching %s... ' % platform, end='')
         checksum = http_download_and_hash(rustup_url(platform, version))
         if validate and checksum != rustup_hash(platform):
             print('mismatch:\n  script: %s\n  server: %s' % (
                 RUSTUP_HASHES[platform], checksum))
         else:
             print('OK')
         hashes.append((platform, checksum))
     return hashes
 
+
 if __name__ == '__main__':
     '''Allow invoking the module as a utility to update checksums.'''
 
     # Unbuffer stdout so our two-part 'Checking...' messages print correctly
     # even if there's network delay.
     sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
 
     # Hook the requests module from the greater source tree. We can't import
--- a/python/mozboot/mozboot/stylo.py
+++ b/python/mozboot/mozboot/stylo.py
@@ -1,8 +1,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/.
 
-from __future__ import print_function, unicode_literals
+from __future__ import absolute_import, print_function, unicode_literals
 
 WINDOWS = 'win64-clang-cl'
 LINUX = 'linux64-clang'
--- a/python/mozboot/mozboot/util.py
+++ b/python/mozboot/mozboot/util.py
@@ -1,12 +1,14 @@
 # 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 absolute_import
+
 import os
 
 
 def get_state_dir():
     """Obtain path to a directory to hold state.
 
     Returns a tuple of the path and a bool indicating whether the
     value came from an environment variable.
--- a/python/mozboot/mozboot/windows.py
+++ b/python/mozboot/mozboot/windows.py
@@ -1,12 +1,14 @@
 # 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 absolute_import, print_function
+
 import os
 import sys
 import subprocess
 
 from mozboot.base import BaseBootstrapper
 
 
 class WindowsBootstrapper(BaseBootstrapper):
@@ -18,38 +20,39 @@ class WindowsBootstrapper(BaseBootstrapp
         'mingw-w64-x86_64-perl',
         'patch',
         'patchutils',
         'diffutils',
         'autoconf2.13',
         'tar',
         'zip',
         'unzip',
-        'mingw-w64-x86_64-toolchain', # TODO: Should be removed when Mercurial is installable from a wheel.
+        'mingw-w64-x86_64-toolchain',  # TODO: Remove when Mercurial is installable from a wheel.
         'mingw-w64-i686-toolchain'
     ]
 
     BROWSER_PACKAGES = [
         'mingw-w64-x86_64-yasm',
         'mingw-w64-i686-nsis'
     ]
 
     MOBILE_ANDROID_COMMON_PACKAGES = [
         'wget'
     ]
 
     def __init__(self, **kwargs):
         if 'MOZ_WINDOWS_BOOTSTRAP' not in os.environ or os.environ['MOZ_WINDOWS_BOOTSTRAP'] != '1':
-            raise NotImplementedError('Bootstrap support for Windows is under development. For now, use MozillaBuild '
-                                      'to set up a build environment on Windows. If you are testing Windows Bootstrap support, '
+            raise NotImplementedError('Bootstrap support for Windows is under development. For '
+                                      'now use MozillaBuild to set up a build environment on '
+                                      'Windows. If you are testing Windows Bootstrap support, '
                                       'try `export MOZ_WINDOWS_BOOTSTRAP=1`')
         BaseBootstrapper.__init__(self, **kwargs)
         if not self.which('pacman'):
-            raise NotImplementedError('The Windows bootstrapper only works with msys2 with pacman. Get msys2 at '
-                                      'http://msys2.github.io/')
+            raise NotImplementedError('The Windows bootstrapper only works with msys2 with '
+                                      'pacman. Get msys2 at http://msys2.github.io/')
         print('Using an experimental bootstrapper for Windows.')
 
     def which(self, name):
         return BaseBootstrapper.which(self, name + '.exe')
 
     def install_system_packages(self):
         self.pacman_install(*self.SYSTEM_PACKAGES)
 
--- a/python/mozboot/setup.py
+++ b/python/mozboot/setup.py
@@ -1,12 +1,14 @@
 # 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 absolute_import
+
 from distutils.core import setup
 
 VERSION = '0.1'
 
 setup(
     name='mozboot',
     description='System bootstrap for building Mozilla projects.',
     license='MPL 2.0',
--- a/tools/lint/flake8.yml
+++ b/tools/lint/flake8.yml
@@ -5,16 +5,17 @@ flake8:
         - build/moz.configure/*.configure
         - build/*.py
         - configure.py
         - config/check_macroassembler_style.py
         - config/mozunit.py
         - layout/tools/reftest
         - python/mach
         - python/mach_commands.py
+        - python/mozboot        
         - python/mozlint
         - python/mozversioncontrol
         - security/manager
         - taskcluster
         - testing/firefox-ui
         - testing/mach_commands.py
         - testing/marionette/client
         - testing/marionette/harness
--- a/tools/lint/py2.yml
+++ b/tools/lint/py2.yml
@@ -24,17 +24,16 @@ py2:
         - modules
         - mozglue
         - netwerk
         - nsprpub
         - other-licenses
         - probes/trace-gen.py
         - python/devtools
         - python/mach
-        - python/mozboot
         - python/mozbuild
         - python/mozversioncontrol
         - security
         - services/common/tests/mach_commands.py
         - servo
         - testing/awsy
         - testing/firefox-ui
         - testing/geckodriver