isort: format codebase

Change-Id: I6f11d123b68fd077f558d3c21349c55c5f251019
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/383715
Reviewed-by: Gavin Mak <gavinmak@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
Commit-Queue: Mike Frysinger <vapier@google.com>
diff --git a/.isort.cfg b/.isort.cfg
new file mode 100644
index 0000000..bc47b61
--- /dev/null
+++ b/.isort.cfg
@@ -0,0 +1,41 @@
+# Copyright 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Config file for the isort python module.
+# This is used to enforce import sorting standards.
+#
+# https://pycqa.github.io/isort/docs/configuration/options.html
+
+[settings]
+# Be compatible with `black` since it also matches what we want.
+profile = black
+
+line_length = 80
+length_sort = false
+force_single_line = true
+lines_after_imports = 2
+from_first = false
+case_sensitive = false
+force_sort_within_sections = true
+order_by_type = false
+
+# Ignore generated files.
+extend_skip_glob = *_pb2.py
+
+# Allow importing multiple classes on a single line from these modules.
+# https://google.github.io/styleguide/pyguide#s2.2-imports
+single_line_exclusions =
+    abc,
+    collections.abc,
+    typing,
diff --git a/color.py b/color.py
index 8f29b59..0f63748 100644
--- a/color.py
+++ b/color.py
@@ -17,6 +17,7 @@
 
 import pager
 
+
 COLORS = {
     None: -1,
     "normal": -1,
diff --git a/command.py b/command.py
index 0205932..9d5d56e 100644
--- a/command.py
+++ b/command.py
@@ -13,14 +13,14 @@
 # limitations under the License.
 
 import multiprocessing
-import os
 import optparse
+import os
 import re
 
-from event_log import EventLog
-from error import NoSuchProjectError
 from error import InvalidProjectGroupsError
+from error import NoSuchProjectError
 from error import RepoExitError
+from event_log import EventLog
 import progress
 
 
diff --git a/editor.py b/editor.py
index 96835ab..78311f1 100644
--- a/editor.py
+++ b/editor.py
@@ -14,8 +14,8 @@
 
 import os
 import re
-import sys
 import subprocess
+import sys
 import tempfile
 
 from error import EditorError
diff --git a/event_log.py b/event_log.py
index b1f8bdf..60c1a43 100644
--- a/event_log.py
+++ b/event_log.py
@@ -15,6 +15,7 @@
 import json
 import multiprocessing
 
+
 TASK_COMMAND = "command"
 TASK_SYNC_NETWORK = "sync-network"
 TASK_SYNC_LOCAL = "sync-local"
diff --git a/fetch.py b/fetch.py
index cf8d1d7..55845af 100644
--- a/fetch.py
+++ b/fetch.py
@@ -18,6 +18,7 @@
 import sys
 from urllib.parse import urlparse
 from urllib.request import urlopen
+
 from error import RepoExitError
 
 
diff --git a/git_command.py b/git_command.py
index 36fcfe7..a5cf514 100644
--- a/git_command.py
+++ b/git_command.py
@@ -14,17 +14,20 @@
 
 import functools
 import os
-import sys
 import subprocess
+import sys
 from typing import Any, Optional
 
 from error import GitError
 from error import RepoExitError
 from git_refs import HEAD
 import platform_utils
-from repo_trace import REPO_TRACE, IsTrace, Trace
+from repo_trace import IsTrace
+from repo_trace import REPO_TRACE
+from repo_trace import Trace
 from wrapper import Wrapper
 
+
 GIT = "git"
 # NB: These do not need to be kept in sync with the repo launcher script.
 # These may be much newer as it allows the repo launcher to roll between
diff --git a/git_config.py b/git_config.py
index 971066e..8c2eb6e 100644
--- a/git_config.py
+++ b/git_config.py
@@ -26,11 +26,15 @@
 import urllib.error
 import urllib.request
 
-from error import GitError, UploadError
+from error import GitError
+from error import UploadError
+from git_command import GitCommand
+from git_refs import R_CHANGES
+from git_refs import R_HEADS
+from git_refs import R_TAGS
 import platform_utils
 from repo_trace import Trace
-from git_command import GitCommand
-from git_refs import R_CHANGES, R_HEADS, R_TAGS
+
 
 # Prefix that is prepended to all the keys of SyncAnalysisState's data
 # that is saved in the config.
diff --git a/git_refs.py b/git_refs.py
index aca1f90..1f5eaab 100644
--- a/git_refs.py
+++ b/git_refs.py
@@ -13,8 +13,10 @@
 # limitations under the License.
 
 import os
-from repo_trace import Trace
+
 import platform_utils
+from repo_trace import Trace
+
 
 HEAD = "HEAD"
 R_CHANGES = "refs/changes/"
diff --git a/git_superproject.py b/git_superproject.py
index f1b4f23..5d8c0d4 100644
--- a/git_superproject.py
+++ b/git_superproject.py
@@ -22,17 +22,19 @@
   UpdateProjectsResult = superproject.UpdateProjectsRevisionId(projects)
 """
 
-import hashlib
 import functools
+import hashlib
 import os
 import sys
 import time
 from typing import NamedTuple
 
-from git_command import git_require, GitCommand
+from git_command import git_require
+from git_command import GitCommand
 from git_config import RepoConfig
 from git_refs import GitRefs
 
+
 _SUPERPROJECT_GIT_NAME = "superproject.git"
 _SUPERPROJECT_MANIFEST_NAME = "superproject_override.xml"
 
diff --git a/git_trace2_event_log.py b/git_trace2_event_log.py
index 5b99867..f26f831 100644
--- a/git_trace2_event_log.py
+++ b/git_trace2_event_log.py
@@ -37,7 +37,8 @@
 import tempfile
 import threading
 
-from git_command import GitCommand, RepoSourceVersion
+from git_command import GitCommand
+from git_command import RepoSourceVersion
 
 
 class EventLog(object):
diff --git a/main.py b/main.py
index 126a4b6..1c7f0af 100755
--- a/main.py
+++ b/main.py
@@ -21,6 +21,7 @@
 """
 
 import getpass
+import json
 import netrc
 import optparse
 import os
@@ -30,7 +31,7 @@
 import textwrap
 import time
 import urllib.request
-import json
+
 
 try:
     import kerberos
@@ -38,31 +39,34 @@
     kerberos = None
 
 from color import SetDefaultColoring
-import event_log
-from repo_trace import SetTrace, Trace, SetTraceToStderr
-from git_command import user_agent
-from git_config import RepoConfig
-from git_trace2_event_log import EventLog
 from command import InteractiveCommand
 from command import MirrorSafeCommand
-from subcmds.version import Version
 from editor import Editor
 from error import DownloadError
+from error import GitcUnsupportedError
 from error import InvalidProjectGroupsError
 from error import ManifestInvalidRevisionError
 from error import NoManifestException
 from error import NoSuchProjectError
 from error import RepoChangedException
+from error import RepoError
 from error import RepoExitError
 from error import RepoUnhandledExceptionError
-from error import RepoError
 from error import SilentRepoExitError
-from error import GitcUnsupportedError
+import event_log
+from git_command import user_agent
+from git_config import RepoConfig
+from git_trace2_event_log import EventLog
 from manifest_xml import RepoClient
-from pager import RunPager, TerminatePager
-from wrapper import WrapperPath, Wrapper
-
+from pager import RunPager
+from pager import TerminatePager
+from repo_trace import SetTrace
+from repo_trace import SetTraceToStderr
+from repo_trace import Trace
 from subcmds import all_commands
+from subcmds.version import Version
+from wrapper import Wrapper
+from wrapper import WrapperPath
 
 
 # NB: These do not need to be kept in sync with the repo launcher script.
diff --git a/manifest_xml.py b/manifest_xml.py
index 80e563a..d944b40 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -18,27 +18,25 @@
 import platform
 import re
 import sys
-import xml.dom.minidom
 import urllib.parse
+import xml.dom.minidom
 
+from error import ManifestInvalidPathError
+from error import ManifestInvalidRevisionError
+from error import ManifestParseError
 from git_config import GitConfig
-from git_refs import R_HEADS, HEAD
+from git_refs import HEAD
+from git_refs import R_HEADS
 from git_superproject import Superproject
 import platform_utils
-from project import (
-    Annotation,
-    RemoteSpec,
-    Project,
-    RepoProject,
-    ManifestProject,
-)
-from error import (
-    ManifestParseError,
-    ManifestInvalidPathError,
-    ManifestInvalidRevisionError,
-)
+from project import Annotation
+from project import ManifestProject
+from project import Project
+from project import RemoteSpec
+from project import RepoProject
 from wrapper import Wrapper
 
+
 MANIFEST_FILE_NAME = "manifest.xml"
 LOCAL_MANIFEST_NAME = "local_manifest.xml"
 LOCAL_MANIFESTS_DIR_NAME = "local_manifests"
diff --git a/pager.py b/pager.py
index 2d51b45..9a4da19 100644
--- a/pager.py
+++ b/pager.py
@@ -19,6 +19,7 @@
 
 import platform_utils
 
+
 active = False
 pager_process = None
 old_stdout = None
diff --git a/platform_utils_win32.py b/platform_utils_win32.py
index e9b15f4..80a5263 100644
--- a/platform_utils_win32.py
+++ b/platform_utils_win32.py
@@ -12,12 +12,28 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from ctypes import addressof
+from ctypes import byref
+from ctypes import c_buffer
+from ctypes import c_ubyte
+from ctypes import FormatError
+from ctypes import get_last_error
+from ctypes import Structure
+from ctypes import Union
+from ctypes import WinDLL
+from ctypes import WinError
+from ctypes.wintypes import BOOL
+from ctypes.wintypes import BOOLEAN
+from ctypes.wintypes import DWORD
+from ctypes.wintypes import HANDLE
+from ctypes.wintypes import LPCWSTR
+from ctypes.wintypes import LPDWORD
+from ctypes.wintypes import LPVOID
+from ctypes.wintypes import ULONG
+from ctypes.wintypes import USHORT
+from ctypes.wintypes import WCHAR
 import errno
 
-from ctypes import WinDLL, get_last_error, FormatError, WinError, addressof
-from ctypes import c_buffer, c_ubyte, Structure, Union, byref
-from ctypes.wintypes import BOOL, BOOLEAN, LPCWSTR, DWORD, HANDLE
-from ctypes.wintypes import WCHAR, USHORT, LPVOID, ULONG, LPDWORD
 
 kernel32 = WinDLL("kernel32", use_last_error=True)
 
diff --git a/progress.py b/progress.py
index f2edf14..80bc946 100644
--- a/progress.py
+++ b/progress.py
@@ -16,6 +16,7 @@
 import sys
 import time
 
+
 try:
     import threading as _threading
 except ImportError:
@@ -23,6 +24,7 @@
 
 from repo_trace import IsTraceToStderr
 
+
 _TTY = sys.stderr.isatty()
 
 # This will erase all content in the current line (wherever the cursor is).
diff --git a/project.py b/project.py
index a3b6312..bf4f9ae 100644
--- a/project.py
+++ b/project.py
@@ -26,35 +26,39 @@
 import tarfile
 import tempfile
 import time
-from typing import NamedTuple, List
+from typing import List, NamedTuple
 import urllib.parse
 
 from color import Coloring
+from error import DownloadError
+from error import GitError
+from error import ManifestInvalidPathError
+from error import ManifestInvalidRevisionError
+from error import ManifestParseError
+from error import NoManifestException
+from error import RepoError
+from error import UploadError
 import fetch
-from git_command import GitCommand, git_require
-from git_config import (
-    GitConfig,
-    IsId,
-    GetSchemeFromUrl,
-    GetUrlCookieFile,
-    ID_RE,
-)
+from git_command import git_require
+from git_command import GitCommand
+from git_config import GetSchemeFromUrl
+from git_config import GetUrlCookieFile
+from git_config import GitConfig
+from git_config import ID_RE
+from git_config import IsId
+from git_refs import GitRefs
+from git_refs import HEAD
+from git_refs import R_HEADS
+from git_refs import R_M
+from git_refs import R_PUB
+from git_refs import R_TAGS
+from git_refs import R_WORKTREE_M
 import git_superproject
 from git_trace2_event_log import EventLog
-from error import (
-    GitError,
-    UploadError,
-    DownloadError,
-    RepoError,
-)
-from error import ManifestInvalidRevisionError, ManifestInvalidPathError
-from error import NoManifestException, ManifestParseError
 import platform_utils
 import progress
 from repo_trace import Trace
 
-from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M, R_WORKTREE_M
-
 
 class SyncNetworkHalfResult(NamedTuple):
     """Sync_NetworkHalf return value."""
diff --git a/release/update-manpages b/release/update-manpages
index 0402ad6..6679b17 100755
--- a/release/update-manpages
+++ b/release/update-manpages
@@ -22,4 +22,5 @@
 
 import update_manpages
 
+
 sys.exit(update_manpages.main(sys.argv[1:]))
diff --git a/release/update_manpages.py b/release/update_manpages.py
index cb68724..489de35 100644
--- a/release/update_manpages.py
+++ b/release/update_manpages.py
@@ -17,17 +17,18 @@
 Most code lives in this module so it can be unittested.
 """
 
-from pathlib import Path
 import argparse
 import functools
 import multiprocessing
 import os
+from pathlib import Path
 import re
 import shutil
 import subprocess
 import sys
 import tempfile
 
+
 TOPDIR = Path(__file__).resolve().parent.parent
 MANDIR = TOPDIR.joinpath("man")
 
diff --git a/repo b/repo
index b9b1928..7923775 100755
--- a/repo
+++ b/repo
@@ -254,11 +254,13 @@
 import shutil
 import stat
 
+
 if sys.version_info[0] == 3:
-  import urllib.request
   import urllib.error
+  import urllib.request
 else:
   import imp
+
   import urllib2
   urllib = imp.new_module('urllib')
   urllib.request = urllib2
diff --git a/repo_logging.py b/repo_logging.py
index 67db05f..b748df4 100644
--- a/repo_logging.py
+++ b/repo_logging.py
@@ -19,6 +19,7 @@
 
 from color import Coloring
 
+
 SEPARATOR = "=" * 80
 
 
diff --git a/repo_trace.py b/repo_trace.py
index 01beaf8..d243ce6 100644
--- a/repo_trace.py
+++ b/repo_trace.py
@@ -21,13 +21,14 @@
 """
 
 import contextlib
-import sys
 import os
-import time
+import sys
 import tempfile
+import time
 
 import platform_utils
 
+
 # Env var to implicitly turn on tracing.
 REPO_TRACE = "REPO_TRACE"
 
diff --git a/run_tests b/run_tests
index 2d92cae..d61308f 100755
--- a/run_tests
+++ b/run_tests
@@ -18,6 +18,7 @@
 import os
 import subprocess
 import sys
+
 import pytest
 
 
@@ -38,12 +39,20 @@
     ).returncode
 
 
+def run_isort():
+    """Returns the exit code from isort."""
+    return subprocess.run(
+        [sys.executable, "-m", "isort", "--check", ROOT_DIR], check=False
+    ).returncode
+
+
 def main(argv):
     """The main entry."""
     checks = (
         lambda: pytest.main(argv),
         run_black,
         run_flake8,
+        run_isort,
     )
     return 0 if all(not c() for c in checks) else 1
 
diff --git a/run_tests.vpython3 b/run_tests.vpython3
index 3d0cd78..036064d 100644
--- a/run_tests.vpython3
+++ b/run_tests.vpython3
@@ -123,3 +123,8 @@
   name: "infra/python/wheels/pycodestyle-py2_py3"
   version: "version:2.10.0"
 >
+
+wheel: <
+  name: "infra/python/wheels/isort-py3"
+  version: "version:5.10.1"
+>
diff --git a/setup.py b/setup.py
index 3e4e6b4..dca44ad 100755
--- a/setup.py
+++ b/setup.py
@@ -16,6 +16,7 @@
 """Python packaging for repo."""
 
 import os
+
 import setuptools
 
 
diff --git a/subcmds/__init__.py b/subcmds/__init__.py
index 0754f70..965ad0b 100644
--- a/subcmds/__init__.py
+++ b/subcmds/__init__.py
@@ -14,6 +14,7 @@
 
 import os
 
+
 # A mapping of the subcommand name to the class that implements it.
 all_commands = {}
 all_modules = []
diff --git a/subcmds/abandon.py b/subcmds/abandon.py
index 1499c75..996c3d2 100644
--- a/subcmds/abandon.py
+++ b/subcmds/abandon.py
@@ -17,10 +17,12 @@
 import itertools
 import sys
 
-from command import Command, DEFAULT_LOCAL_JOBS
+from command import Command
+from command import DEFAULT_LOCAL_JOBS
+from error import RepoError
+from error import RepoExitError
 from git_command import git
 from progress import Progress
-from error import RepoError, RepoExitError
 
 
 class AbandonError(RepoExitError):
diff --git a/subcmds/branches.py b/subcmds/branches.py
index 4d5bb19..33523c3 100644
--- a/subcmds/branches.py
+++ b/subcmds/branches.py
@@ -16,7 +16,8 @@
 import sys
 
 from color import Coloring
-from command import Command, DEFAULT_LOCAL_JOBS
+from command import Command
+from command import DEFAULT_LOCAL_JOBS
 
 
 class BranchColoring(Coloring):
diff --git a/subcmds/checkout.py b/subcmds/checkout.py
index 033fd34..67f1838 100644
--- a/subcmds/checkout.py
+++ b/subcmds/checkout.py
@@ -14,12 +14,14 @@
 
 import functools
 import sys
-
 from typing import NamedTuple
-from command import Command, DEFAULT_LOCAL_JOBS
+
+from command import Command
+from command import DEFAULT_LOCAL_JOBS
+from error import GitError
+from error import RepoExitError
 from progress import Progress
 from project import Project
-from error import GitError, RepoExitError
 
 
 class CheckoutBranchResult(NamedTuple):
diff --git a/subcmds/cherry_pick.py b/subcmds/cherry_pick.py
index 7a4dd09..980720e 100644
--- a/subcmds/cherry_pick.py
+++ b/subcmds/cherry_pick.py
@@ -14,9 +14,11 @@
 
 import re
 import sys
+
 from command import Command
-from git_command import GitCommand
 from error import GitError
+from git_command import GitCommand
+
 
 CHANGE_ID_RE = re.compile(r"^\s*Change-Id: I([0-9a-f]{40})\s*$")
 
diff --git a/subcmds/diff.py b/subcmds/diff.py
index 5c627c0..d9d72b4 100644
--- a/subcmds/diff.py
+++ b/subcmds/diff.py
@@ -15,7 +15,8 @@
 import functools
 import io
 
-from command import DEFAULT_LOCAL_JOBS, PagedCommand
+from command import DEFAULT_LOCAL_JOBS
+from command import PagedCommand
 
 
 class Diff(PagedCommand):
diff --git a/subcmds/download.py b/subcmds/download.py
index 18e555b..e33698e 100644
--- a/subcmds/download.py
+++ b/subcmds/download.py
@@ -16,7 +16,10 @@
 import sys
 
 from command import Command
-from error import GitError, NoSuchProjectError, RepoExitError
+from error import GitError
+from error import NoSuchProjectError
+from error import RepoExitError
+
 
 CHANGE_RE = re.compile(r"^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$")
 
diff --git a/subcmds/forall.py b/subcmds/forall.py
index 0a89735..9a02c49 100644
--- a/subcmds/forall.py
+++ b/subcmds/forall.py
@@ -16,21 +16,20 @@
 import functools
 import io
 import multiprocessing
-import re
 import os
+import re
 import signal
-import sys
 import subprocess
+import sys
 
 from color import Coloring
-from command import (
-    DEFAULT_LOCAL_JOBS,
-    Command,
-    MirrorSafeCommand,
-    WORKER_BATCH_SIZE,
-)
+from command import Command
+from command import DEFAULT_LOCAL_JOBS
+from command import MirrorSafeCommand
+from command import WORKER_BATCH_SIZE
 from error import ManifestInvalidRevisionError
 
+
 _CAN_COLOR = [
     "branch",
     "diff",
diff --git a/subcmds/grep.py b/subcmds/grep.py
index 9ebd776..19c06d4 100644
--- a/subcmds/grep.py
+++ b/subcmds/grep.py
@@ -14,12 +14,15 @@
 
 import functools
 import sys
+from typing import NamedTuple
 
 from color import Coloring
-from command import DEFAULT_LOCAL_JOBS, PagedCommand
-from error import GitError, InvalidArgumentsError, SilentRepoExitError
+from command import DEFAULT_LOCAL_JOBS
+from command import PagedCommand
+from error import GitError
+from error import InvalidArgumentsError
+from error import SilentRepoExitError
 from git_command import GitCommand
-from typing import NamedTuple
 from project import Project
 
 
diff --git a/subcmds/help.py b/subcmds/help.py
index 0d7b664..a839131 100644
--- a/subcmds/help.py
+++ b/subcmds/help.py
@@ -16,14 +16,12 @@
 import sys
 import textwrap
 
-from subcmds import all_commands
 from color import Coloring
-from command import (
-    PagedCommand,
-    MirrorSafeCommand,
-)
-from wrapper import Wrapper
+from command import MirrorSafeCommand
+from command import PagedCommand
 from error import RepoExitError
+from subcmds import all_commands
+from wrapper import Wrapper
 
 
 class InvalidHelpCommand(RepoExitError):
diff --git a/subcmds/info.py b/subcmds/info.py
index 6e7f3ed..c24682c 100644
--- a/subcmds/info.py
+++ b/subcmds/info.py
@@ -14,9 +14,10 @@
 
 import optparse
 
-from command import PagedCommand
 from color import Coloring
-from git_refs import R_M, R_HEADS
+from command import PagedCommand
+from git_refs import R_HEADS
+from git_refs import R_M
 
 
 class _Coloring(Coloring):
diff --git a/subcmds/init.py b/subcmds/init.py
index c5a2c54..529b212 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -16,11 +16,15 @@
 import sys
 
 from color import Coloring
-from command import InteractiveCommand, MirrorSafeCommand
-from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD
-from wrapper import Wrapper
-from error import UpdateManifestError
+from command import InteractiveCommand
+from command import MirrorSafeCommand
 from error import RepoUnhandledExceptionError
+from error import UpdateManifestError
+from git_command import git_require
+from git_command import MIN_GIT_VERSION_HARD
+from git_command import MIN_GIT_VERSION_SOFT
+from wrapper import Wrapper
+
 
 _REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW")
 
diff --git a/subcmds/list.py b/subcmds/list.py
index 24e3e1f..fba6a4d 100644
--- a/subcmds/list.py
+++ b/subcmds/list.py
@@ -14,7 +14,8 @@
 
 import os
 
-from command import Command, MirrorSafeCommand
+from command import Command
+from command import MirrorSafeCommand
 
 
 class List(Command, MirrorSafeCommand):
diff --git a/subcmds/prune.py b/subcmds/prune.py
index 5a68c14..f18471f 100644
--- a/subcmds/prune.py
+++ b/subcmds/prune.py
@@ -15,7 +15,8 @@
 import itertools
 
 from color import Coloring
-from command import DEFAULT_LOCAL_JOBS, PagedCommand
+from command import DEFAULT_LOCAL_JOBS
+from command import PagedCommand
 
 
 class Prune(PagedCommand):
diff --git a/subcmds/selfupdate.py b/subcmds/selfupdate.py
index 983fd63..51d963e 100644
--- a/subcmds/selfupdate.py
+++ b/subcmds/selfupdate.py
@@ -15,10 +15,11 @@
 import optparse
 import sys
 
-from command import Command, MirrorSafeCommand
-from subcmds.sync import _PostRepoUpgrade
-from subcmds.sync import _PostRepoFetch
+from command import Command
+from command import MirrorSafeCommand
 from error import RepoExitError
+from subcmds.sync import _PostRepoFetch
+from subcmds.sync import _PostRepoUpgrade
 
 
 class SelfupdateError(RepoExitError):
diff --git a/subcmds/start.py b/subcmds/start.py
index 481d9ef..7a42b26 100644
--- a/subcmds/start.py
+++ b/subcmds/start.py
@@ -14,14 +14,15 @@
 
 import functools
 import sys
+from typing import NamedTuple
 
-from command import Command, DEFAULT_LOCAL_JOBS
-from git_config import IsImmutable
+from command import Command
+from command import DEFAULT_LOCAL_JOBS
+from error import RepoExitError
 from git_command import git
+from git_config import IsImmutable
 from progress import Progress
 from project import Project
-from typing import NamedTuple
-from error import RepoExitError
 
 
 class ExecuteOneResult(NamedTuple):
diff --git a/subcmds/status.py b/subcmds/status.py
index 6e0026f..dac61ab 100644
--- a/subcmds/status.py
+++ b/subcmds/status.py
@@ -17,9 +17,9 @@
 import io
 import os
 
-from command import DEFAULT_LOCAL_JOBS, PagedCommand
-
 from color import Coloring
+from command import DEFAULT_LOCAL_JOBS
+from command import PagedCommand
 import platform_utils
 
 
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 74bc455..13c964b 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -25,13 +25,14 @@
 import sys
 import tempfile
 import time
-from typing import NamedTuple, List, Set
+from typing import List, NamedTuple, Set
 import urllib.error
 import urllib.parse
 import urllib.request
 import xml.parsers.expat
 import xmlrpc.client
 
+
 try:
     import threading as _threading
 except ImportError:
@@ -49,34 +50,35 @@
         return (256, 256)
 
 
+from command import Command
+from command import DEFAULT_LOCAL_JOBS
+from command import MirrorSafeCommand
+from command import WORKER_BATCH_SIZE
+from error import GitError
+from error import RepoChangedException
+from error import RepoExitError
+from error import RepoUnhandledExceptionError
+from error import SyncError
+from error import UpdateManifestError
 import event_log
 from git_command import git_require
 from git_config import GetUrlCookieFile
-from git_refs import R_HEADS, HEAD
+from git_refs import HEAD
+from git_refs import R_HEADS
 import git_superproject
+import platform_utils
+from progress import elapsed_str
+from progress import jobs_str
+from progress import Progress
+from project import DeleteWorktreeError
 from project import Project
 from project import RemoteSpec
-from command import (
-    Command,
-    DEFAULT_LOCAL_JOBS,
-    MirrorSafeCommand,
-    WORKER_BATCH_SIZE,
-)
-from error import (
-    RepoChangedException,
-    GitError,
-    RepoExitError,
-    SyncError,
-    UpdateManifestError,
-    RepoUnhandledExceptionError,
-)
-import platform_utils
-from project import SyncBuffer, DeleteWorktreeError
-from progress import Progress, elapsed_str, jobs_str
+from project import SyncBuffer
 from repo_trace import Trace
 import ssh
 from wrapper import Wrapper
 
+
 _ONE_DAY_S = 24 * 60 * 60
 
 # Env var to implicitly turn auto-gc back on.  This was added to allow a user to
diff --git a/subcmds/upload.py b/subcmds/upload.py
index b89525c..ec89ad4 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -19,9 +19,12 @@
 import sys
 from typing import List
 
-from command import DEFAULT_LOCAL_JOBS, InteractiveCommand
+from command import DEFAULT_LOCAL_JOBS
+from command import InteractiveCommand
 from editor import Editor
-from error import UploadError, SilentRepoExitError, GitError
+from error import GitError
+from error import SilentRepoExitError
+from error import UploadError
 from git_command import GitCommand
 from git_refs import R_HEADS
 from hooks import RepoHook
diff --git a/subcmds/version.py b/subcmds/version.py
index c539db6..71a0360 100644
--- a/subcmds/version.py
+++ b/subcmds/version.py
@@ -15,8 +15,11 @@
 import platform
 import sys
 
-from command import Command, MirrorSafeCommand
-from git_command import git, RepoSourceVersion, user_agent
+from command import Command
+from command import MirrorSafeCommand
+from git_command import git
+from git_command import RepoSourceVersion
+from git_command import user_agent
 from git_refs import HEAD
 from wrapper import Wrapper
 
diff --git a/tests/test_error.py b/tests/test_error.py
index 2b28f5c..a74ed2d 100644
--- a/tests/test_error.py
+++ b/tests/test_error.py
@@ -18,13 +18,14 @@
 import pickle
 import unittest
 
-import error
-import project
-import git_command
-import fetch
 import command
+import error
+import fetch
+import git_command
+import project
 from subcmds import all_modules
 
+
 imports = all_modules + [
     error,
     project,
diff --git a/tests/test_git_command.py b/tests/test_git_command.py
index 3dd31b2..c803d28 100644
--- a/tests/test_git_command.py
+++ b/tests/test_git_command.py
@@ -14,11 +14,12 @@
 
 """Unittests for the git_command.py module."""
 
-import re
 import os
+import re
 import subprocess
 import unittest
 
+
 try:
     from unittest import mock
 except ImportError:
diff --git a/tests/test_git_superproject.py b/tests/test_git_superproject.py
index eb542c6..f884f50 100644
--- a/tests/test_git_superproject.py
+++ b/tests/test_git_superproject.py
@@ -21,10 +21,11 @@
 import unittest
 from unittest import mock
 
+from test_manifest_xml import sort_attributes
+
 import git_superproject
 import git_trace2_event_log
 import manifest_xml
-from test_manifest_xml import sort_attributes
 
 
 class SuperprojectTestCase(unittest.TestCase):
diff --git a/tests/test_hooks.py b/tests/test_hooks.py
index 7827712..76e928f 100644
--- a/tests/test_hooks.py
+++ b/tests/test_hooks.py
@@ -14,9 +14,10 @@
 
 """Unittests for the hooks.py module."""
 
-import hooks
 import unittest
 
+import hooks
+
 
 class RepoHookShebang(unittest.TestCase):
     """Check shebang parsing in RepoHook."""
diff --git a/tests/test_project.py b/tests/test_project.py
index bc8330b..79728d7 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -22,9 +22,9 @@
 import unittest
 
 import error
-import manifest_xml
 import git_command
 import git_config
+import manifest_xml
 import platform_utils
 import project
 
diff --git a/tests/test_subcmds_sync.py b/tests/test_subcmds_sync.py
index 71b0f8e..b9f0a74 100644
--- a/tests/test_subcmds_sync.py
+++ b/tests/test_subcmds_sync.py
@@ -16,16 +16,17 @@
 import os
 import shutil
 import tempfile
-import unittest
 import time
+import unittest
 from unittest import mock
 
 import pytest
 
 import command
-from subcmds import sync
+from error import GitError
+from error import RepoExitError
 from project import SyncNetworkHalfResult
-from error import GitError, RepoExitError
+from subcmds import sync
 
 
 @pytest.mark.parametrize(
diff --git a/tests/test_subcmds_upload.py b/tests/test_subcmds_upload.py
index 7581199..cd88897 100644
--- a/tests/test_subcmds_upload.py
+++ b/tests/test_subcmds_upload.py
@@ -17,8 +17,9 @@
 import unittest
 from unittest import mock
 
+from error import GitError
+from error import UploadError
 from subcmds import upload
-from error import UploadError, GitError
 
 
 class UnexpectedError(Exception):