Add isort pre-commit and lint with isort and yapf in CI (#1093)

* add empty .isort.cfg

* force_single_line

* add pre-commit-config, apply sort

* remove unused pre-commit-hooks

* Lint with isort

* Lint with Yapf.

* move yapftests to its own section

* verbose output
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6cc5028..23e9f8e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -32,3 +32,11 @@
         pip install pytest
         pip install pytest-cov
         pytest
+    - name: Lint with isort
+      run: |
+        pip install isort
+        isort . --check --diff
+    - name: Lint with yapf
+      run: |
+        pip install .
+        yapf . -vv --diff --recursive
diff --git a/.isort.cfg b/.isort.cfg
new file mode 100644
index 0000000..69720b9
--- /dev/null
+++ b/.isort.cfg
@@ -0,0 +1,5 @@
+[settings]
+force_single_line=true
+known_yapftests=yapftests
+
+sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER,YAPFTESTS
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3bd65c2..049a1a2 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,6 +2,11 @@
 # to enable run `pip install pre-commit && pre-commit install`
 
 repos:
+  - repo: https://github.com/pycqa/isort
+    rev: 5.11.5
+    hooks:
+      - id: isort
+        name: isort (python)
   - repo: local
     hooks:
       - id: yapf
@@ -15,15 +20,12 @@
     hooks:
       - id: trailing-whitespace
       - id: check-docstring-first
-      - id: check-json
       - id: check-added-large-files
       - id: check-yaml
       - id: debug-statements
-      - id: requirements-txt-fixer
       - id: check-merge-conflict
       - id: double-quote-string-fixer
       - id: end-of-file-fixer
-      - id: sort-simple-yaml
   - repo: meta
     hooks:
       - id: check-hooks-apply
diff --git a/setup.py b/setup.py
index 0412f67..106d2b1 100644
--- a/setup.py
+++ b/setup.py
@@ -17,7 +17,9 @@
 import sys
 import unittest
 
-from setuptools import find_packages, setup, Command
+from setuptools import Command
+from setuptools import find_packages
+from setuptools import setup
 
 import yapf
 
diff --git a/third_party/yapf_diff/yapf_diff.py b/third_party/yapf_diff/yapf_diff.py
index adc6fe4..a22abd9 100644
--- a/third_party/yapf_diff/yapf_diff.py
+++ b/third_party/yapf_diff/yapf_diff.py
@@ -30,7 +30,6 @@
 import re
 import subprocess
 import sys
-
 from io import StringIO
 
 
diff --git a/yapf/__init__.py b/yapf/__init__.py
index 39b15c9..aa5c37b 100644
--- a/yapf/__init__.py
+++ b/yapf/__init__.py
@@ -200,8 +200,8 @@
   """
   changed = False
   if parallel:
-    import multiprocessing  # pylint: disable=g-import-not-at-top
     import concurrent.futures  # pylint: disable=g-import-not-at-top
+    import multiprocessing  # pylint: disable=g-import-not-at-top
     workers = min(multiprocessing.cpu_count(), len(filenames))
     with concurrent.futures.ProcessPoolExecutor(workers) as executor:
       future_formats = [
diff --git a/yapf/pytree/blank_line_calculator.py b/yapf/pytree/blank_line_calculator.py
index d47f2b5..7bccb09 100644
--- a/yapf/pytree/blank_line_calculator.py
+++ b/yapf/pytree/blank_line_calculator.py
@@ -174,5 +174,4 @@
 
 
 def _AsyncFunction(node):
-  return (node.prev_sibling and
-          node.prev_sibling.type == grammar_token.ASYNC)
+  return (node.prev_sibling and node.prev_sibling.type == grammar_token.ASYNC)
diff --git a/yapf/pytree/pytree_utils.py b/yapf/pytree/pytree_utils.py
index 43ef876..8b3c406 100644
--- a/yapf/pytree/pytree_utils.py
+++ b/yapf/pytree/pytree_utils.py
@@ -26,7 +26,6 @@
 
 import ast
 import os
-
 from lib2to3 import pygram
 from lib2to3 import pytree
 from lib2to3.pgen2 import driver
diff --git a/yapf/pytree/pytree_visitor.py b/yapf/pytree/pytree_visitor.py
index 314431e..4f6c605 100644
--- a/yapf/pytree/pytree_visitor.py
+++ b/yapf/pytree/pytree_visitor.py
@@ -25,7 +25,6 @@
 """
 
 import sys
-
 from lib2to3 import pytree
 
 from yapf.pytree import pytree_utils
diff --git a/yapf/pytree/split_penalty.py b/yapf/pytree/split_penalty.py
index 81163e4..ccb3880 100644
--- a/yapf/pytree/split_penalty.py
+++ b/yapf/pytree/split_penalty.py
@@ -14,7 +14,6 @@
 """Computation of split penalties before/between tokens."""
 
 import re
-
 from lib2to3 import pytree
 from lib2to3.pgen2 import token as grammar_token
 
diff --git a/yapf/yapflib/format_token.py b/yapf/yapflib/format_token.py
index 41afd45..c572391 100644
--- a/yapf/yapflib/format_token.py
+++ b/yapf/yapflib/format_token.py
@@ -15,7 +15,6 @@
 
 import keyword
 import re
-
 from functools import lru_cache
 from lib2to3.pgen2 import token
 
diff --git a/yapf/yapflib/logical_line.py b/yapf/yapflib/logical_line.py
index 1528fc4..780db8a 100644
--- a/yapf/yapflib/logical_line.py
+++ b/yapf/yapflib/logical_line.py
@@ -19,14 +19,14 @@
 perform the wrapping required to comply with the style guide.
 """
 
+from lib2to3.fixer_util import syms as python_symbols
+
 from yapf.pytree import pytree_utils
 from yapf.pytree import split_penalty
 from yapf.yapflib import format_token
 from yapf.yapflib import style
 from yapf.yapflib import subtypes
 
-from lib2to3.fixer_util import syms as python_symbols
-
 
 class LogicalLine(object):
   """Represents a single logical line in the output.
diff --git a/yapf/yapflib/reformatter.py b/yapf/yapflib/reformatter.py
index f8c4bc4..b7c883e 100644
--- a/yapf/yapflib/reformatter.py
+++ b/yapf/yapflib/reformatter.py
@@ -22,7 +22,6 @@
 import collections
 import heapq
 import re
-
 from lib2to3 import pytree
 from lib2to3.pgen2 import token
 
diff --git a/yapf/yapflib/yapf_api.py b/yapf/yapflib/yapf_api.py
index 19e86f0..be5467a 100644
--- a/yapf/yapflib/yapf_api.py
+++ b/yapf/yapflib/yapf_api.py
@@ -38,12 +38,11 @@
 import sys
 
 from yapf.pyparser import pyparser
-
-from yapf.pytree import pytree_unwrapper
-from yapf.pytree import pytree_utils
 from yapf.pytree import blank_line_calculator
 from yapf.pytree import comment_splicer
 from yapf.pytree import continuation_splicer
+from yapf.pytree import pytree_unwrapper
+from yapf.pytree import pytree_utils
 from yapf.pytree import split_penalty
 from yapf.pytree import subtype_assigner
 from yapf.yapflib import errors
diff --git a/yapftests/comment_splicer_test.py b/yapftests/comment_splicer_test.py
index 36c25b2..64cb708 100644
--- a/yapftests/comment_splicer_test.py
+++ b/yapftests/comment_splicer_test.py
@@ -16,8 +16,8 @@
 import textwrap
 import unittest
 
-from yapf.pytree import pytree_utils
 from yapf.pytree import comment_splicer
+from yapf.pytree import pytree_utils
 
 
 class CommentSplicerTest(unittest.TestCase):
diff --git a/yapftests/format_decision_state_test.py b/yapftests/format_decision_state_test.py
index 63961f3..3bff578 100644
--- a/yapftests/format_decision_state_test.py
+++ b/yapftests/format_decision_state_test.py
@@ -17,7 +17,6 @@
 import unittest
 
 from yapf.pytree import pytree_utils
-
 from yapf.yapflib import format_decision_state
 from yapf.yapflib import logical_line
 from yapf.yapflib import style
diff --git a/yapftests/format_token_test.py b/yapftests/format_token_test.py
index 18ebe48..5703e5a 100644
--- a/yapftests/format_token_test.py
+++ b/yapftests/format_token_test.py
@@ -14,7 +14,6 @@
 """Tests for yapf.format_token."""
 
 import unittest
-
 from lib2to3 import pytree
 from lib2to3.pgen2 import token
 
diff --git a/yapftests/logical_line_test.py b/yapftests/logical_line_test.py
index d18262a..9188b32 100644
--- a/yapftests/logical_line_test.py
+++ b/yapftests/logical_line_test.py
@@ -15,7 +15,6 @@
 
 import textwrap
 import unittest
-
 from lib2to3 import pytree
 from lib2to3.pgen2 import token
 
diff --git a/yapftests/main_test.py b/yapftests/main_test.py
index 7241a02..b5d9b92 100644
--- a/yapftests/main_test.py
+++ b/yapftests/main_test.py
@@ -14,10 +14,11 @@
 # limitations under the License.
 """Tests for yapf.__init__.main."""
 
-from contextlib import contextmanager
-from io import StringIO
 import sys
 import unittest
+from contextlib import contextmanager
+from io import StringIO
+
 import yapf
 
 from yapftests import yapf_test_helper
diff --git a/yapftests/pytree_utils_test.py b/yapftests/pytree_utils_test.py
index c55f668..b228fcb 100644
--- a/yapftests/pytree_utils_test.py
+++ b/yapftests/pytree_utils_test.py
@@ -14,7 +14,6 @@
 """Tests for yapf.pytree_utils."""
 
 import unittest
-
 from lib2to3 import pygram
 from lib2to3 import pytree
 from lib2to3.pgen2 import token
diff --git a/yapftests/split_penalty_test.py b/yapftests/split_penalty_test.py
index f7474a3..c08cf5a 100644
--- a/yapftests/split_penalty_test.py
+++ b/yapftests/split_penalty_test.py
@@ -16,7 +16,6 @@
 import sys
 import textwrap
 import unittest
-
 from lib2to3 import pytree
 
 from yapf.pytree import pytree_utils
diff --git a/yapftests/yapf_test.py b/yapftests/yapf_test.py
index 33cc143..09659e7 100644
--- a/yapftests/yapf_test.py
+++ b/yapftests/yapf_test.py
@@ -23,7 +23,6 @@
 import tempfile
 import textwrap
 import unittest
-
 from io import StringIO
 from lib2to3.pgen2 import tokenize
 
@@ -285,8 +284,9 @@
     with self.assertRaises(IOError) as context:
       yapf_api.FormatFile('not_a_file.py')
 
-    self.assertEqual(str(context.exception),
-                     "[Errno 2] No such file or directory: 'not_a_file.py'")
+    self.assertEqual(
+        str(context.exception),
+        "[Errno 2] No such file or directory: 'not_a_file.py'")
 
   def testCommentsUnformatted(self):
     code = textwrap.dedent("""\