drop python3.6 support
python 3.6 reached end of life on 2021-12-23
Committed via https://github.com/asottile/all-repos
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d5d4778..4b49600 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -25,12 +25,12 @@
rev: v2.6.0
hooks:
- id: reorder-python-imports
- args: [--py3-plus]
+ args: [--py37-plus, --add-import, 'from __future__ import annotations']
- repo: https://github.com/asottile/pyupgrade
rev: v2.31.0
hooks:
- id: pyupgrade
- args: [--py36-plus]
+ args: [--py37-plus]
- repo: https://github.com/asottile/add-trailing-comma
rev: v2.2.1
hooks:
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 58dc61d..d54596e 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -10,7 +10,7 @@
type: github
endpoint: github
name: asottile/azure-pipeline-templates
- ref: refs/tags/v2.1.0
+ ref: refs/tags/v2.4.0
jobs:
- template: job--python-tox.yml@asottile
@@ -19,5 +19,5 @@
os: windows
- template: job--python-tox.yml@asottile
parameters:
- toxenvs: [pypy3, py36, py37, py38]
+ toxenvs: [py37, py38, py39, py310]
os: linux
diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py
index e1beb4e..79c8d4e 100644
--- a/pre_commit_hooks/check_added_large_files.py
+++ b/pre_commit_hooks/check_added_large_files.py
@@ -1,16 +1,16 @@
+from __future__ import annotations
+
import argparse
import math
import os
import subprocess
-from typing import Optional
from typing import Sequence
-from typing import Set
from pre_commit_hooks.util import added_files
from pre_commit_hooks.util import zsplit
-def filter_lfs_files(filenames: Set[str]) -> None: # pragma: no cover (lfs)
+def filter_lfs_files(filenames: set[str]) -> None: # pragma: no cover (lfs)
"""Remove files tracked by git-lfs from the set."""
if not filenames:
return
@@ -54,7 +54,7 @@
return retv
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'filenames', nargs='*',
diff --git a/pre_commit_hooks/check_ast.py b/pre_commit_hooks/check_ast.py
index ab5661d..fdac361 100644
--- a/pre_commit_hooks/check_ast.py
+++ b/pre_commit_hooks/check_ast.py
@@ -1,13 +1,14 @@
+from __future__ import annotations
+
import argparse
import ast
import platform
import sys
import traceback
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_builtin_literals.py b/pre_commit_hooks/check_builtin_literals.py
index 3fbae3e..d3054aa 100644
--- a/pre_commit_hooks/check_builtin_literals.py
+++ b/pre_commit_hooks/check_builtin_literals.py
@@ -1,10 +1,9 @@
+from __future__ import annotations
+
import argparse
import ast
-from typing import List
from typing import NamedTuple
-from typing import Optional
from typing import Sequence
-from typing import Set
BUILTIN_TYPES = {
@@ -27,10 +26,10 @@
class Visitor(ast.NodeVisitor):
def __init__(
self,
- ignore: Optional[Sequence[str]] = None,
+ ignore: Sequence[str] | None = None,
allow_dict_kwargs: bool = True,
) -> None:
- self.builtin_type_calls: List[Call] = []
+ self.builtin_type_calls: list[Call] = []
self.ignore = set(ignore) if ignore else set()
self.allow_dict_kwargs = allow_dict_kwargs
@@ -56,9 +55,9 @@
def check_file(
filename: str,
- ignore: Optional[Sequence[str]] = None,
+ ignore: Sequence[str] | None = None,
allow_dict_kwargs: bool = True,
-) -> List[Call]:
+) -> list[Call]:
with open(filename, 'rb') as f:
tree = ast.parse(f.read(), filename=filename)
visitor = Visitor(ignore=ignore, allow_dict_kwargs=allow_dict_kwargs)
@@ -66,11 +65,11 @@
return visitor.builtin_type_calls
-def parse_ignore(value: str) -> Set[str]:
+def parse_ignore(value: str) -> set[str]:
return set(value.split(','))
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
parser.add_argument('--ignore', type=parse_ignore, default=set())
diff --git a/pre_commit_hooks/check_byte_order_marker.py b/pre_commit_hooks/check_byte_order_marker.py
index fda05e8..59cc561 100644
--- a/pre_commit_hooks/check_byte_order_marker.py
+++ b/pre_commit_hooks/check_byte_order_marker.py
@@ -1,9 +1,10 @@
+from __future__ import annotations
+
import argparse
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py
index c3f39db..33a13f1 100644
--- a/pre_commit_hooks/check_case_conflict.py
+++ b/pre_commit_hooks/check_case_conflict.py
@@ -1,15 +1,15 @@
+from __future__ import annotations
+
import argparse
from typing import Iterable
from typing import Iterator
-from typing import Optional
from typing import Sequence
-from typing import Set
from pre_commit_hooks.util import added_files
from pre_commit_hooks.util import cmd_output
-def lower_set(iterable: Iterable[str]) -> Set[str]:
+def lower_set(iterable: Iterable[str]) -> set[str]:
return {x.lower() for x in iterable}
@@ -21,7 +21,7 @@
path_parts.pop()
-def directories_for(files: Set[str]) -> Set[str]:
+def directories_for(files: set[str]) -> set[str]:
return {parent for file in files for parent in parents(file)}
@@ -56,7 +56,7 @@
return retv
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'filenames', nargs='*',
diff --git a/pre_commit_hooks/check_docstring_first.py b/pre_commit_hooks/check_docstring_first.py
index 875c0fb..1744919 100644
--- a/pre_commit_hooks/check_docstring_first.py
+++ b/pre_commit_hooks/check_docstring_first.py
@@ -1,8 +1,9 @@
+from __future__ import annotations
+
import argparse
import io
import tokenize
from tokenize import tokenize as tokenize_tokenize
-from typing import Optional
from typing import Sequence
NON_CODE_TOKENS = frozenset((
@@ -45,7 +46,7 @@
return 0
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py
index 34af5ca..6b5402a 100644
--- a/pre_commit_hooks/check_executables_have_shebangs.py
+++ b/pre_commit_hooks/check_executables_have_shebangs.py
@@ -1,13 +1,12 @@
"""Check that executable text files have a shebang."""
+from __future__ import annotations
+
import argparse
import shlex
import sys
from typing import Generator
-from typing import List
from typing import NamedTuple
-from typing import Optional
from typing import Sequence
-from typing import Set
from pre_commit_hooks.util import cmd_output
from pre_commit_hooks.util import zsplit
@@ -15,7 +14,7 @@
EXECUTABLE_VALUES = frozenset(('1', '3', '5', '7'))
-def check_executables(paths: List[str]) -> int:
+def check_executables(paths: list[str]) -> int:
if sys.platform == 'win32': # pragma: win32 cover
return _check_git_filemode(paths)
else: # pragma: win32 no cover
@@ -42,7 +41,7 @@
def _check_git_filemode(paths: Sequence[str]) -> int:
- seen: Set[str] = set()
+ seen: set[str] = set()
for ls_file in git_ls_files(paths):
is_executable = any(b in EXECUTABLE_VALUES for b in ls_file.mode[-3:])
if is_executable and not has_shebang(ls_file.filename):
@@ -71,7 +70,7 @@
)
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py
index 96ba024..6a679fe 100644
--- a/pre_commit_hooks/check_json.py
+++ b/pre_commit_hooks/check_json.py
@@ -1,16 +1,14 @@
+from __future__ import annotations
+
import argparse
import json
from typing import Any
-from typing import Dict
-from typing import List
-from typing import Optional
from typing import Sequence
-from typing import Tuple
def raise_duplicate_keys(
- ordered_pairs: List[Tuple[str, Any]],
-) -> Dict[str, Any]:
+ ordered_pairs: list[tuple[str, Any]],
+) -> dict[str, Any]:
d = {}
for key, val in ordered_pairs:
if key in d:
@@ -20,7 +18,7 @@
return d
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check.')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py
index aed1e9c..22031a2 100644
--- a/pre_commit_hooks/check_merge_conflict.py
+++ b/pre_commit_hooks/check_merge_conflict.py
@@ -1,6 +1,7 @@
+from __future__ import annotations
+
import argparse
import os.path
-from typing import Optional
from typing import Sequence
from pre_commit_hooks.util import cmd_output
@@ -26,7 +27,7 @@
)
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
parser.add_argument('--assume-in-merge', action='store_true')
diff --git a/pre_commit_hooks/check_shebang_scripts_are_executable.py b/pre_commit_hooks/check_shebang_scripts_are_executable.py
index 50bc9c0..0f35650 100644
--- a/pre_commit_hooks/check_shebang_scripts_are_executable.py
+++ b/pre_commit_hooks/check_shebang_scripts_are_executable.py
@@ -1,18 +1,17 @@
"""Check that text files with a shebang are executable."""
+from __future__ import annotations
+
import argparse
import shlex
import sys
-from typing import List
-from typing import Optional
from typing import Sequence
-from typing import Set
from pre_commit_hooks.check_executables_have_shebangs import EXECUTABLE_VALUES
from pre_commit_hooks.check_executables_have_shebangs import git_ls_files
from pre_commit_hooks.check_executables_have_shebangs import has_shebang
-def check_shebangs(paths: List[str]) -> int:
+def check_shebangs(paths: list[str]) -> int:
# Cannot optimize on non-executability here if we intend this check to
# work on win32 -- and that's where problems caused by non-executability
# (elsewhere) are most likely to arise from.
@@ -20,7 +19,7 @@
def _check_git_filemode(paths: Sequence[str]) -> int:
- seen: Set[str] = set()
+ seen: set[str] = set()
for ls_file in git_ls_files(paths):
is_executable = any(b in EXECUTABLE_VALUES for b in ls_file.mode[-3:])
if not is_executable and has_shebang(ls_file.filename):
@@ -41,7 +40,7 @@
)
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_symlinks.py b/pre_commit_hooks/check_symlinks.py
index db3b4fe..a85c82a 100644
--- a/pre_commit_hooks/check_symlinks.py
+++ b/pre_commit_hooks/check_symlinks.py
@@ -1,10 +1,11 @@
+from __future__ import annotations
+
import argparse
import os.path
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description='Checks for broken symlinks.')
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py
index f623e68..88f7086 100644
--- a/pre_commit_hooks/check_toml.py
+++ b/pre_commit_hooks/check_toml.py
@@ -1,11 +1,12 @@
+from __future__ import annotations
+
import argparse
-from typing import Optional
from typing import Sequence
import toml
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check.')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_vcs_permalinks.py b/pre_commit_hooks/check_vcs_permalinks.py
index 1c77b9a..68639bd 100644
--- a/pre_commit_hooks/check_vcs_permalinks.py
+++ b/pre_commit_hooks/check_vcs_permalinks.py
@@ -1,8 +1,8 @@
+from __future__ import annotations
+
import argparse
import re
import sys
-from typing import List
-from typing import Optional
from typing import Pattern
from typing import Sequence
@@ -15,7 +15,7 @@
return re.compile(regex.encode())
-def _check_filename(filename: str, patterns: List[Pattern[bytes]]) -> int:
+def _check_filename(filename: str, patterns: list[Pattern[bytes]]) -> int:
retv = 0
with open(filename, 'rb') as f:
for i, line in enumerate(f, 1):
@@ -28,7 +28,7 @@
return retv
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
parser.add_argument(
diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py
index 0fa6bb2..c256af9 100644
--- a/pre_commit_hooks/check_xml.py
+++ b/pre_commit_hooks/check_xml.py
@@ -1,10 +1,11 @@
+from __future__ import annotations
+
import argparse
import xml.sax.handler
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='XML filenames to check.')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py
index 5e86b73..250794e 100644
--- a/pre_commit_hooks/check_yaml.py
+++ b/pre_commit_hooks/check_yaml.py
@@ -1,8 +1,9 @@
+from __future__ import annotations
+
import argparse
from typing import Any
from typing import Generator
from typing import NamedTuple
-from typing import Optional
from typing import Sequence
import ruamel.yaml
@@ -36,7 +37,7 @@
}
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'-m', '--multi', '--allow-multiple-documents', action='store_true',
diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py
index f78d6d6..00b6798 100644
--- a/pre_commit_hooks/debug_statement_hook.py
+++ b/pre_commit_hooks/debug_statement_hook.py
@@ -1,9 +1,9 @@
+from __future__ import annotations
+
import argparse
import ast
import traceback
-from typing import List
from typing import NamedTuple
-from typing import Optional
from typing import Sequence
@@ -29,7 +29,7 @@
class DebugStatementParser(ast.NodeVisitor):
def __init__(self) -> None:
- self.breakpoints: List[Debug] = []
+ self.breakpoints: list[Debug] = []
def visit_Import(self, node: ast.Import) -> None:
for name in node.names:
@@ -70,7 +70,7 @@
return int(bool(visitor.breakpoints))
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to run')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/destroyed_symlinks.py b/pre_commit_hooks/destroyed_symlinks.py
index a3f122f..88253c0 100644
--- a/pre_commit_hooks/destroyed_symlinks.py
+++ b/pre_commit_hooks/destroyed_symlinks.py
@@ -1,8 +1,8 @@
+from __future__ import annotations
+
import argparse
import shlex
import subprocess
-from typing import List
-from typing import Optional
from typing import Sequence
from pre_commit_hooks.util import cmd_output
@@ -13,8 +13,8 @@
PERMS_NONEXIST = '000000'
-def find_destroyed_symlinks(files: Sequence[str]) -> List[str]:
- destroyed_links: List[str] = []
+def find_destroyed_symlinks(files: Sequence[str]) -> list[str]:
+ destroyed_links: list[str] = []
if not files:
return destroyed_links
for line in zsplit(
@@ -66,7 +66,7 @@
return destroyed_links
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check.')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py
index ba1d789..4f59d9c 100644
--- a/pre_commit_hooks/detect_aws_credentials.py
+++ b/pre_commit_hooks/detect_aws_credentials.py
@@ -1,11 +1,10 @@
+from __future__ import annotations
+
import argparse
import configparser
import os
-from typing import List
from typing import NamedTuple
-from typing import Optional
from typing import Sequence
-from typing import Set
class BadFile(NamedTuple):
@@ -13,7 +12,7 @@
key: str
-def get_aws_cred_files_from_env() -> Set[str]:
+def get_aws_cred_files_from_env() -> set[str]:
"""Extract credential file paths from environment variables."""
return {
os.environ[env_var]
@@ -25,7 +24,7 @@
}
-def get_aws_secrets_from_env() -> Set[str]:
+def get_aws_secrets_from_env() -> set[str]:
"""Extract AWS secrets from environment variables."""
keys = set()
for env_var in (
@@ -36,7 +35,7 @@
return keys
-def get_aws_secrets_from_file(credentials_file: str) -> Set[str]:
+def get_aws_secrets_from_file(credentials_file: str) -> set[str]:
"""Extract AWS secrets from configuration files.
Read an ini-style configuration file and return a set with all found AWS
@@ -69,8 +68,8 @@
def check_file_for_aws_keys(
filenames: Sequence[str],
- keys: Set[bytes],
-) -> List[BadFile]:
+ keys: set[bytes],
+) -> list[BadFile]:
"""Check if files contain AWS secrets.
Return a list of all files containing AWS secrets and keys found, with all
@@ -90,7 +89,7 @@
return bad_files
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='+', help='Filenames to run')
parser.add_argument(
@@ -119,7 +118,7 @@
# of files to to gather AWS secrets from.
credential_files |= get_aws_cred_files_from_env()
- keys: Set[str] = set()
+ keys: set[str] = set()
for credential_file in credential_files:
keys |= get_aws_secrets_from_file(credential_file)
diff --git a/pre_commit_hooks/detect_private_key.py b/pre_commit_hooks/detect_private_key.py
index 18f9539..cd51f90 100644
--- a/pre_commit_hooks/detect_private_key.py
+++ b/pre_commit_hooks/detect_private_key.py
@@ -1,5 +1,6 @@
+from __future__ import annotations
+
import argparse
-from typing import Optional
from typing import Sequence
BLACKLIST = [
@@ -16,7 +17,7 @@
]
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/end_of_file_fixer.py b/pre_commit_hooks/end_of_file_fixer.py
index 40e8821..a30dce9 100644
--- a/pre_commit_hooks/end_of_file_fixer.py
+++ b/pre_commit_hooks/end_of_file_fixer.py
@@ -1,7 +1,8 @@
+from __future__ import annotations
+
import argparse
import os
from typing import IO
-from typing import Optional
from typing import Sequence
@@ -48,7 +49,7 @@
return 0
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to fix')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py
index 392e226..c5691f0 100644
--- a/pre_commit_hooks/file_contents_sorter.py
+++ b/pre_commit_hooks/file_contents_sorter.py
@@ -9,12 +9,13 @@
this hook on that file should reduce the instances of git merge
conflicts and keep the file nicely ordered.
"""
+from __future__ import annotations
+
import argparse
from typing import Any
from typing import Callable
from typing import IO
from typing import Iterable
-from typing import Optional
from typing import Sequence
PASS = 0
@@ -23,7 +24,7 @@
def sort_file_contents(
f: IO[bytes],
- key: Optional[Callable[[bytes], Any]],
+ key: Callable[[bytes], Any] | None,
*,
unique: bool = False,
) -> int:
@@ -47,7 +48,7 @@
return FAIL
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='+', help='Files to sort')
parser.add_argument(
diff --git a/pre_commit_hooks/fix_byte_order_marker.py b/pre_commit_hooks/fix_byte_order_marker.py
index 51b94e1..22a4990 100644
--- a/pre_commit_hooks/fix_byte_order_marker.py
+++ b/pre_commit_hooks/fix_byte_order_marker.py
@@ -1,9 +1,10 @@
+from __future__ import annotations
+
import argparse
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py
index c704774..60c71ee 100644
--- a/pre_commit_hooks/fix_encoding_pragma.py
+++ b/pre_commit_hooks/fix_encoding_pragma.py
@@ -1,7 +1,8 @@
+from __future__ import annotations
+
import argparse
from typing import IO
from typing import NamedTuple
-from typing import Optional
from typing import Sequence
DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-'
@@ -26,7 +27,7 @@
# True: has exactly the coding pragma expected
# False: missing coding pragma entirely
# None: has a coding pragma, but it does not match
- pragma_status: Optional[bool]
+ pragma_status: bool | None
ending: bytes
@property
@@ -55,7 +56,7 @@
rest = second_line + rest
if potential_coding.rstrip(b'\r\n') == expected_pragma:
- pragma_status: Optional[bool] = True
+ pragma_status: bool | None = True
elif has_coding(potential_coding):
pragma_status = None
else:
@@ -105,7 +106,7 @@
return pragma.encode().rstrip()
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(
'Fixes the encoding pragma of python files',
)
diff --git a/pre_commit_hooks/forbid_new_submodules.py b/pre_commit_hooks/forbid_new_submodules.py
index 0275808..b806cad 100644
--- a/pre_commit_hooks/forbid_new_submodules.py
+++ b/pre_commit_hooks/forbid_new_submodules.py
@@ -1,12 +1,13 @@
+from __future__ import annotations
+
import argparse
import os
-from typing import Optional
from typing import Sequence
from pre_commit_hooks.util import cmd_output
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/mixed_line_ending.py b/pre_commit_hooks/mixed_line_ending.py
index 4e07ed9..0328e86 100644
--- a/pre_commit_hooks/mixed_line_ending.py
+++ b/pre_commit_hooks/mixed_line_ending.py
@@ -1,7 +1,7 @@
+from __future__ import annotations
+
import argparse
import collections
-from typing import Dict
-from typing import Optional
from typing import Sequence
@@ -25,7 +25,7 @@
with open(filename, 'rb') as f:
contents = f.read()
- counts: Dict[bytes, int] = collections.defaultdict(int)
+ counts: dict[bytes, int] = collections.defaultdict(int)
for line in contents.splitlines(True):
for ending in ALL_ENDINGS:
@@ -62,7 +62,7 @@
return other_endings
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'-f', '--fix',
diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py
index db84850..741f726 100644
--- a/pre_commit_hooks/no_commit_to_branch.py
+++ b/pre_commit_hooks/no_commit_to_branch.py
@@ -1,7 +1,8 @@
+from __future__ import annotations
+
import argparse
import re
from typing import AbstractSet
-from typing import Optional
from typing import Sequence
from pre_commit_hooks.util import CalledProcessError
@@ -23,7 +24,7 @@
)
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'-b', '--branch', action='append',
diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py
index 33ad5a1..627a11c 100644
--- a/pre_commit_hooks/pretty_format_json.py
+++ b/pre_commit_hooks/pretty_format_json.py
@@ -1,13 +1,11 @@
+from __future__ import annotations
+
import argparse
import json
import sys
from difflib import unified_diff
-from typing import List
from typing import Mapping
-from typing import Optional
from typing import Sequence
-from typing import Tuple
-from typing import Union
def _get_pretty_format(
@@ -17,7 +15,7 @@
sort_keys: bool = True,
top_keys: Sequence[str] = (),
) -> str:
- def pairs_first(pairs: Sequence[Tuple[str, str]]) -> Mapping[str, str]:
+ def pairs_first(pairs: Sequence[tuple[str, str]]) -> Mapping[str, str]:
before = [pair for pair in pairs if pair[0] in top_keys]
before = sorted(before, key=lambda x: top_keys.index(x[0]))
after = [pair for pair in pairs if pair[0] not in top_keys]
@@ -38,7 +36,7 @@
f.write(new_contents)
-def parse_num_to_int(s: str) -> Union[int, str]:
+def parse_num_to_int(s: str) -> int | str:
"""Convert string numbers to int, leaving strings as is."""
try:
return int(s)
@@ -46,7 +44,7 @@
return s
-def parse_topkeys(s: str) -> List[str]:
+def parse_topkeys(s: str) -> list[str]:
return s.split(',')
@@ -57,7 +55,7 @@
return ''.join(diff)
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'--autofix',
diff --git a/pre_commit_hooks/removed.py b/pre_commit_hooks/removed.py
index 236cbf8..6f6c7b7 100644
--- a/pre_commit_hooks/removed.py
+++ b/pre_commit_hooks/removed.py
@@ -1,9 +1,10 @@
+from __future__ import annotations
+
import sys
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
argv = argv if argv is not None else sys.argv[1:]
hookid, new_hookid, url = argv[:3]
raise SystemExit(
diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py
index 63f891f..5884394 100644
--- a/pre_commit_hooks/requirements_txt_fixer.py
+++ b/pre_commit_hooks/requirements_txt_fixer.py
@@ -1,8 +1,8 @@
+from __future__ import annotations
+
import argparse
import re
from typing import IO
-from typing import List
-from typing import Optional
from typing import Sequence
@@ -15,8 +15,8 @@
UNTIL_SEP = re.compile(rb'[^;\s]+')
def __init__(self) -> None:
- self.value: Optional[bytes] = None
- self.comments: List[bytes] = []
+ self.value: bytes | None = None
+ self.comments: list[bytes] = []
@property
def name(self) -> bytes:
@@ -36,7 +36,7 @@
return name[:m.start()]
- def __lt__(self, requirement: 'Requirement') -> bool:
+ def __lt__(self, requirement: Requirement) -> bool:
# \n means top of file comment, so always return True,
# otherwise just do a string comparison with value.
assert self.value is not None, self.value
@@ -61,9 +61,9 @@
def fix_requirements(f: IO[bytes]) -> int:
- requirements: List[Requirement] = []
+ requirements: list[Requirement] = []
before = list(f)
- after: List[bytes] = []
+ after: list[bytes] = []
before_string = b''.join(before)
@@ -130,7 +130,7 @@
return FAIL
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to fix')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py
index 39f683e..116b5c1 100644
--- a/pre_commit_hooks/sort_simple_yaml.py
+++ b/pre_commit_hooks/sort_simple_yaml.py
@@ -17,16 +17,16 @@
In other words, we don't sort deeper than the top layer, and might corrupt
complicated YAML files.
"""
+from __future__ import annotations
+
import argparse
-from typing import List
-from typing import Optional
from typing import Sequence
QUOTES = ["'", '"']
-def sort(lines: List[str]) -> List[str]:
+def sort(lines: list[str]) -> list[str]:
"""Sort a YAML file in alphabetical order, keeping blocks together.
:param lines: array of strings (without newlines)
@@ -44,7 +44,7 @@
return new_lines
-def parse_block(lines: List[str], header: bool = False) -> List[str]:
+def parse_block(lines: list[str], header: bool = False) -> list[str]:
"""Parse and return a single block, popping off the start of `lines`.
If parsing a header block, we stop after we reach a line that is not a
@@ -60,7 +60,7 @@
return block_lines
-def parse_blocks(lines: List[str]) -> List[List[str]]:
+def parse_blocks(lines: list[str]) -> list[list[str]]:
"""Parse and return all possible blocks, popping off the start of `lines`.
:param lines: list of lines
@@ -77,7 +77,7 @@
return blocks
-def first_key(lines: List[str]) -> str:
+def first_key(lines: list[str]) -> str:
"""Returns a string representing the sort key of a block.
The sort key is the first YAML key we encounter, ignoring comments, and
@@ -99,7 +99,7 @@
return '' # not actually reached in reality
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to fix')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py
index a08a5f7..0ef9bc7 100644
--- a/pre_commit_hooks/string_fixer.py
+++ b/pre_commit_hooks/string_fixer.py
@@ -1,9 +1,9 @@
+from __future__ import annotations
+
import argparse
import io
import re
import tokenize
-from typing import List
-from typing import Optional
from typing import Sequence
START_QUOTE_RE = re.compile('^[a-zA-Z]*"')
@@ -24,7 +24,7 @@
return token_text
-def get_line_offsets_by_line_no(src: str) -> List[int]:
+def get_line_offsets_by_line_no(src: str) -> list[int]:
# Padded so we can index with line number
offsets = [-1, 0]
for line in src.splitlines(True):
@@ -60,7 +60,7 @@
return 0
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to fix')
args = parser.parse_args(argv)
diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py
index bffb0c4..e1ffe36 100644
--- a/pre_commit_hooks/tests_should_end_in_test.py
+++ b/pre_commit_hooks/tests_should_end_in_test.py
@@ -1,11 +1,12 @@
+from __future__ import annotations
+
import argparse
import os.path
import re
-from typing import Optional
from typing import Sequence
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
parser.add_argument(
diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py
index 82faa2d..84f5067 100644
--- a/pre_commit_hooks/trailing_whitespace_fixer.py
+++ b/pre_commit_hooks/trailing_whitespace_fixer.py
@@ -1,13 +1,14 @@
+from __future__ import annotations
+
import argparse
import os
-from typing import Optional
from typing import Sequence
def _fix_file(
filename: str,
is_markdown: bool,
- chars: Optional[bytes],
+ chars: bytes | None,
) -> bool:
with open(filename, mode='rb') as file_processed:
lines = file_processed.readlines()
@@ -24,7 +25,7 @@
def _process_line(
line: bytes,
is_markdown: bool,
- chars: Optional[bytes],
+ chars: bytes | None,
) -> bytes:
if line[-2:] == b'\r\n':
eol = b'\r\n'
@@ -40,7 +41,7 @@
return line.rstrip(chars) + eol
-def main(argv: Optional[Sequence[str]] = None) -> int:
+def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
'--no-markdown-linebreak-ext',
diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py
index 402e33e..d6c90ae 100644
--- a/pre_commit_hooks/util.py
+++ b/pre_commit_hooks/util.py
@@ -1,20 +1,19 @@
+from __future__ import annotations
+
import subprocess
from typing import Any
-from typing import List
-from typing import Optional
-from typing import Set
class CalledProcessError(RuntimeError):
pass
-def added_files() -> Set[str]:
+def added_files() -> set[str]:
cmd = ('git', 'diff', '--staged', '--name-only', '--diff-filter=A')
return set(cmd_output(*cmd).splitlines())
-def cmd_output(*cmd: str, retcode: Optional[int] = 0, **kwargs: Any) -> str:
+def cmd_output(*cmd: str, retcode: int | None = 0, **kwargs: Any) -> str:
kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('stderr', subprocess.PIPE)
proc = subprocess.Popen(cmd, **kwargs)
@@ -25,7 +24,7 @@
return stdout
-def zsplit(s: str) -> List[str]:
+def zsplit(s: str) -> list[str]:
s = s.strip('\0')
if s:
return s.split('\0')
diff --git a/setup.cfg b/setup.cfg
index 45498eb..5b0f7ca 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -13,7 +13,6 @@
License :: OSI Approved :: MIT License
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
- Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
@@ -26,7 +25,7 @@
install_requires =
ruamel.yaml>=0.15
toml
-python_requires = >=3.6.1
+python_requires = >=3.7
[options.packages.find]
exclude =
diff --git a/setup.py b/setup.py
index 8bf1ba9..3d93aef 100644
--- a/setup.py
+++ b/setup.py
@@ -1,2 +1,4 @@
+from __future__ import annotations
+
from setuptools import setup
setup()
diff --git a/testing/util.py b/testing/util.py
index 5043754..2bbbe64 100644
--- a/testing/util.py
+++ b/testing/util.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os.path
import subprocess
diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py
index c16bf5a..54c4e68 100644
--- a/tests/check_added_large_files_test.py
+++ b/tests/check_added_large_files_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import shutil
import pytest
diff --git a/tests/check_ast_test.py b/tests/check_ast_test.py
index 686fd11..6243966 100644
--- a/tests/check_ast_test.py
+++ b/tests/check_ast_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks.check_ast import main
from testing.util import get_resource_path
diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py
index e936798..1b18257 100644
--- a/tests/check_builtin_literals_test.py
+++ b/tests/check_builtin_literals_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import ast
import pytest
diff --git a/tests/check_byte_order_marker_test.py b/tests/check_byte_order_marker_test.py
index 4c40247..909a39b 100644
--- a/tests/check_byte_order_marker_test.py
+++ b/tests/check_byte_order_marker_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks import check_byte_order_marker
diff --git a/tests/check_case_conflict_test.py b/tests/check_case_conflict_test.py
index d9211b5..a914f45 100644
--- a/tests/check_case_conflict_test.py
+++ b/tests/check_case_conflict_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import sys
import pytest
diff --git a/tests/check_docstring_first_test.py b/tests/check_docstring_first_test.py
index ed5c08e..079896f 100644
--- a/tests/check_docstring_first_test.py
+++ b/tests/check_docstring_first_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.check_docstring_first import check_docstring_first
diff --git a/tests/check_executables_have_shebangs_test.py b/tests/check_executables_have_shebangs_test.py
index 5703ede..82d03e3 100644
--- a/tests/check_executables_have_shebangs_test.py
+++ b/tests/check_executables_have_shebangs_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import sys
diff --git a/tests/check_json_test.py b/tests/check_json_test.py
index 3ec67f1..53e1f52 100644
--- a/tests/check_json_test.py
+++ b/tests/check_json_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.check_json import main
diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py
index 79c1b11..d3322db 100644
--- a/tests/check_merge_conflict_test.py
+++ b/tests/check_merge_conflict_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import shutil
diff --git a/tests/check_shebang_scripts_are_executable_test.py b/tests/check_shebang_scripts_are_executable_test.py
index 9e78b06..e4bd07c 100644
--- a/tests/check_shebang_scripts_are_executable_test.py
+++ b/tests/check_shebang_scripts_are_executable_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import pytest
diff --git a/tests/check_symlinks_test.py b/tests/check_symlinks_test.py
index 07c1168..e2c2c78 100644
--- a/tests/check_symlinks_test.py
+++ b/tests/check_symlinks_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import pytest
diff --git a/tests/check_toml_test.py b/tests/check_toml_test.py
index c7251eb..d594f81 100644
--- a/tests/check_toml_test.py
+++ b/tests/check_toml_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks.check_toml import main
diff --git a/tests/check_vcs_permalinks_test.py b/tests/check_vcs_permalinks_test.py
index ad59151..01ce94d 100644
--- a/tests/check_vcs_permalinks_test.py
+++ b/tests/check_vcs_permalinks_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks.check_vcs_permalinks import main
diff --git a/tests/check_xml_test.py b/tests/check_xml_test.py
index 357bad6..767619f 100644
--- a/tests/check_xml_test.py
+++ b/tests/check_xml_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.check_xml import main
diff --git a/tests/check_yaml_test.py b/tests/check_yaml_test.py
index 1a017a1..54eb16e 100644
--- a/tests/check_yaml_test.py
+++ b/tests/check_yaml_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.check_yaml import main
diff --git a/tests/conftest.py b/tests/conftest.py
index f92cfc1..807f15b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.util import cmd_output
diff --git a/tests/debug_statement_hook_test.py b/tests/debug_statement_hook_test.py
index 428421a..349fe89 100644
--- a/tests/debug_statement_hook_test.py
+++ b/tests/debug_statement_hook_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import ast
from pre_commit_hooks.debug_statement_hook import Debug
diff --git a/tests/destroyed_symlinks_test.py b/tests/destroyed_symlinks_test.py
index cde06cf..39c474a 100644
--- a/tests/destroyed_symlinks_test.py
+++ b/tests/destroyed_symlinks_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import subprocess
diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py
index 7212509..afda47a 100644
--- a/tests/detect_aws_credentials_test.py
+++ b/tests/detect_aws_credentials_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from unittest.mock import patch
import pytest
diff --git a/tests/detect_private_key_test.py b/tests/detect_private_key_test.py
index d2c724f..41f8bae 100644
--- a/tests/detect_private_key_test.py
+++ b/tests/detect_private_key_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.detect_private_key import main
diff --git a/tests/end_of_file_fixer_test.py b/tests/end_of_file_fixer_test.py
index 60b9e82..8a5d889 100644
--- a/tests/end_of_file_fixer_test.py
+++ b/tests/end_of_file_fixer_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import io
import pytest
diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py
index 15f1134..5e79e40 100644
--- a/tests/file_contents_sorter_test.py
+++ b/tests/file_contents_sorter_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.file_contents_sorter import FAIL
diff --git a/tests/fix_byte_order_marker_test.py b/tests/fix_byte_order_marker_test.py
index da150e3..d7a6599 100644
--- a/tests/fix_byte_order_marker_test.py
+++ b/tests/fix_byte_order_marker_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks import fix_byte_order_marker
diff --git a/tests/fix_encoding_pragma_test.py b/tests/fix_encoding_pragma_test.py
index f3afa09..98557e9 100644
--- a/tests/fix_encoding_pragma_test.py
+++ b/tests/fix_encoding_pragma_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import io
import pytest
diff --git a/tests/forbid_new_submodules_test.py b/tests/forbid_new_submodules_test.py
index 0326d94..058a329 100644
--- a/tests/forbid_new_submodules_test.py
+++ b/tests/forbid_new_submodules_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import subprocess
from unittest import mock
diff --git a/tests/mixed_line_ending_test.py b/tests/mixed_line_ending_test.py
index f1c2641..a7e7971 100644
--- a/tests/mixed_line_ending_test.py
+++ b/tests/mixed_line_ending_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.mixed_line_ending import main
diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py
index 9fcb580..eaae5e6 100644
--- a/tests/no_commit_to_branch_test.py
+++ b/tests/no_commit_to_branch_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.no_commit_to_branch import is_on_branch
diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py
index 7fda23b..5ded724 100644
--- a/tests/pretty_format_json_test.py
+++ b/tests/pretty_format_json_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import shutil
diff --git a/tests/readme_test.py b/tests/readme_test.py
index 7df7fcf..038868d 100644
--- a/tests/readme_test.py
+++ b/tests/readme_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks.check_yaml import yaml
diff --git a/tests/removed_test.py b/tests/removed_test.py
index d635eb1..cd66957 100644
--- a/tests/removed_test.py
+++ b/tests/removed_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.removed import main
diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py
index e3c6ed5..b725afa 100644
--- a/tests/requirements_txt_fixer_test.py
+++ b/tests/requirements_txt_fixer_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.requirements_txt_fixer import FAIL
diff --git a/tests/sort_simple_yaml_test.py b/tests/sort_simple_yaml_test.py
index a682c15..6cbda85 100644
--- a/tests/sort_simple_yaml_test.py
+++ b/tests/sort_simple_yaml_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import os
import pytest
diff --git a/tests/string_fixer_test.py b/tests/string_fixer_test.py
index 6ddb0ac..9dd7315 100644
--- a/tests/string_fixer_test.py
+++ b/tests/string_fixer_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import textwrap
import pytest
diff --git a/tests/tests_should_end_in_test_test.py b/tests/tests_should_end_in_test_test.py
index 4df2963..dc3744b 100644
--- a/tests/tests_should_end_in_test_test.py
+++ b/tests/tests_should_end_in_test_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from pre_commit_hooks.tests_should_end_in_test import main
diff --git a/tests/trailing_whitespace_fixer_test.py b/tests/trailing_whitespace_fixer_test.py
index bb3b62d..c07497a 100644
--- a/tests/trailing_whitespace_fixer_test.py
+++ b/tests/trailing_whitespace_fixer_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.trailing_whitespace_fixer import main
diff --git a/tests/util_test.py b/tests/util_test.py
index 7f48816..92473e5 100644
--- a/tests/util_test.py
+++ b/tests/util_test.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import pytest
from pre_commit_hooks.util import CalledProcessError
diff --git a/tox.ini b/tox.ini
index 790ce7f..cb2b92a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py36,py37,py38,pypy3,pre-commit
+envlist = py37,py38,pypy3,pre-commit
[testenv]
deps = -rrequirements-dev.txt