Merge pull request #719 from pre-commit/all-repos_autofix_drop-py36

drop python3.6 support
This commit is contained in:
Anthony Sottile 2022-01-15 19:36:25 -05:00 committed by GitHub
commit 77dcefca95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 229 additions and 145 deletions

View File

@ -25,12 +25,12 @@ repos:
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:

View File

@ -10,7 +10,7 @@ resources:
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 @@ jobs:
os: windows
- template: job--python-tox.yml@asottile
parameters:
toxenvs: [pypy3, py36, py37, py38]
toxenvs: [py37, py38, py39, py310]
os: linux

View File

@ -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 @@ def find_large_added_files(
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='*',

View File

@ -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)

View File

@ -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 Call(NamedTuple):
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 @@ class Visitor(ast.NodeVisitor):
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 @@ def check_file(
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())

View File

@ -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)

View File

@ -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 @@ def parents(file: str) -> Iterator[str]:
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 @@ def find_conflicting_filenames(filenames: Sequence[str]) -> int:
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='*',

View File

@ -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 @@ def check_docstring_first(src: bytes, filename: str = '<unknown>') -> int:
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)

View File

@ -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 @@ from pre_commit_hooks.util import zsplit
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 git_ls_files(paths: Sequence[str]) -> Generator[GitLsFile, None, None]:
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 _message(path: str) -> None:
)
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)

View File

@ -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 @@ def raise_duplicate_keys(
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)

View File

@ -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 is_in_merge() -> bool:
)
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')

View File

@ -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_shebangs(paths: List[str]) -> int:
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 _message(path: str) -> None:
)
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)

View File

@ -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)

View File

@ -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)

View File

@ -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 @@ def _get_pattern(domain: str) -> Pattern[bytes]:
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 @@ def _check_filename(filename: str, patterns: List[Pattern[bytes]]) -> int:
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(

View File

@ -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)

View File

@ -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 @@ LOAD_FNS = {
}
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',

View File

@ -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 Debug(NamedTuple):
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 @@ def check_file(filename: str) -> int:
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)

View File

@ -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_LINK = '120000'
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 @@ def find_destroyed_symlinks(files: Sequence[str]) -> List[str]:
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)

View File

@ -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 @@ class BadFile(NamedTuple):
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_cred_files_from_env() -> Set[str]:
}
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 @@ def get_aws_secrets_from_env() -> Set[str]:
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 get_aws_secrets_from_file(credentials_file: str) -> Set[str]:
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 @@ def check_file_for_aws_keys(
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 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
# 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)

View File

@ -1,5 +1,6 @@
from __future__ import annotations
import argparse
from typing import Optional
from typing import Sequence
BLACKLIST = [
@ -16,7 +17,7 @@ BLACKLIST = [
]
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)

View File

@ -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 @@ def fix_file(file_obj: IO[bytes]) -> int:
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)

View File

@ -9,12 +9,13 @@ per line. Various users are adding/removing lines from this file; using
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 @@ FAIL = 1
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 @@ def sort_file_contents(
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(

View File

@ -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)

View File

@ -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 @@ class ExpectedContents(NamedTuple):
# 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 @@ def _get_expected_contents(
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 @@ def _normalize_pragma(pragma: str) -> bytes:
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',
)

View File

@ -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)

View File

@ -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 @@ def fix_filename(filename: str, fix: str) -> int:
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 @@ def fix_filename(filename: str, fix: str) -> int:
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',

View File

@ -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 is_on_branch(
)
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',

View File

@ -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 @@ def _get_pretty_format(
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 @@ def _autofix(filename: str, new_contents: str) -> None:
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 @@ def parse_num_to_int(s: str) -> Union[int, str]:
return s
def parse_topkeys(s: str) -> List[str]:
def parse_topkeys(s: str) -> list[str]:
return s.split(',')
@ -57,7 +55,7 @@ def get_diff(source: str, target: str, file: str) -> str:
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',

View File

@ -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(

View File

@ -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 @@ class Requirement:
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 @@ class Requirement:
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 @@ class Requirement:
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 @@ def fix_requirements(f: IO[bytes]) -> int:
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)

View File

@ -17,16 +17,16 @@ We assume a strict subset of YAML that looks like:
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 @@ def sort(lines: List[str]) -> List[str]:
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 @@ def parse_block(lines: List[str], header: bool = False) -> List[str]:
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 @@ def parse_blocks(lines: List[str]) -> List[List[str]]:
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 @@ def first_key(lines: List[str]) -> str:
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)

View File

@ -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 @@ def handle_match(token_text: str) -> str:
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 @@ def fix_strings(filename: str) -> int:
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)

View File

@ -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(

View File

@ -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 _fix_file(
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 @@ def _process_line(
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',

View File

@ -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 @@ def cmd_output(*cmd: str, retcode: Optional[int] = 0, **kwargs: Any) -> str:
return stdout
def zsplit(s: str) -> List[str]:
def zsplit(s: str) -> list[str]:
s = s.strip('\0')
if s:
return s.split('\0')

View File

@ -13,7 +13,6 @@ classifiers =
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 @@ packages = find:
install_requires =
ruamel.yaml>=0.15
toml
python_requires = >=3.6.1
python_requires = >=3.7
[options.packages.find]
exclude =

View File

@ -1,2 +1,4 @@
from __future__ import annotations
from setuptools import setup
setup()

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os.path
import subprocess

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import shutil
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks.check_ast import main
from testing.util import get_resource_path

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import ast
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks import check_byte_order_marker

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import sys
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.check_docstring_first import check_docstring_first

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import sys

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.check_json import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import shutil

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks.check_toml import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks.check_vcs_permalinks import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.check_xml import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.check_yaml import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.util import cmd_output

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import ast
from pre_commit_hooks.debug_statement_hook import Debug

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import subprocess

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from unittest.mock import patch
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.detect_private_key import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import io
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.file_contents_sorter import FAIL

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks import fix_byte_order_marker

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import io
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import subprocess
from unittest import mock

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.mixed_line_ending import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.no_commit_to_branch import is_on_branch

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import shutil

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks.check_yaml import yaml

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.removed import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.requirements_txt_fixer import FAIL

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import os
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import textwrap
import pytest

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from pre_commit_hooks.tests_should_end_in_test import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.trailing_whitespace_fixer import main

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pytest
from pre_commit_hooks.util import CalledProcessError

View File

@ -1,5 +1,5 @@
[tox]
envlist = py36,py37,py38,pypy3,pre-commit
envlist = py37,py38,pypy3,pre-commit
[testenv]
deps = -rrequirements-dev.txt