From a7626390387e153c3ff75edc353e3d8a8a73374a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Fri, 28 Dec 2018 13:09:17 -0800 Subject: [PATCH 001/334] switch from pyyaml to ruamel.yaml --- pre_commit_hooks/check_yaml.py | 12 +++++------- setup.py | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 9fbbd88d..208737f1 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -4,12 +4,9 @@ import collections import sys -import yaml +import ruamel.yaml -try: - from yaml.cyaml import CSafeLoader as Loader -except ImportError: # pragma: no cover (no libyaml-dev / pypy) - Loader = yaml.SafeLoader +yaml = ruamel.yaml.YAML(typ='safe') def _exhaust(gen): @@ -57,8 +54,9 @@ def check_yaml(argv=None): retval = 0 for filename in args.filenames: try: - load_fn(open(filename), Loader=Loader) - except yaml.YAMLError as exc: + with open(filename) as f: + load_fn(f) + except ruamel.yaml.YAMLError as exc: print(exc) retval = 1 return retval diff --git a/setup.py b/setup.py index 99d2430a..84892a7c 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ packages=find_packages(exclude=('tests*', 'testing*')), install_requires=[ 'flake8', - 'pyyaml', + 'ruamel.yaml>=0.15', 'six', ], entry_points={ From e7158ce14dbaad1c8907e075b051def16b6f518b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 2 Jan 2019 10:31:51 -0800 Subject: [PATCH 002/334] pre-commit autoupdate --- .pre-commit-config.yaml | 10 +++++----- pre_commit_hooks/check_symlinks.py | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4207d94b..74f4c123 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,23 +13,23 @@ repos: - id: requirements-txt-fixer - id: flake8 - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.4 + rev: v1.4.3 hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v1.7.0 + rev: v1.13.0 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports - rev: v1.0.1 + rev: v1.3.4 hooks: - id: reorder-python-imports language_version: python2.7 - repo: https://github.com/asottile/pyupgrade - rev: v1.2.0 + rev: v1.11.0 hooks: - id: pyupgrade - repo: https://github.com/asottile/add-trailing-comma - rev: v0.6.4 + rev: v0.7.1 hooks: - id: add-trailing-comma diff --git a/pre_commit_hooks/check_symlinks.py b/pre_commit_hooks/check_symlinks.py index fd80089c..010c8715 100644 --- a/pre_commit_hooks/check_symlinks.py +++ b/pre_commit_hooks/check_symlinks.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import argparse -import os import os.path From 3709f5b2c467bddbdd66fe43e85bbd5f3b7c4bcf Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 14 Jan 2019 20:59:50 -0800 Subject: [PATCH 003/334] remove sudo: in .travis.yml https://blog.travis-ci.com/2018-11-19-required-linux-infrastructure-migration Committed via https://github.com/asottile/all-repos --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 28688337..477b5c4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: python -sudo: false matrix: include: # These should match the tox env list - env: TOXENV=py27 @@ -7,7 +6,6 @@ matrix: python: 3.6 - env: TOXENV=py37 python: 3.7 - sudo: required dist: xenial - env: TOXENV=pypy python: pypy-5.7.1 From 2c2991645675a1d6dcd554c7546660e90228634f Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 27 Jan 2019 09:25:18 -0800 Subject: [PATCH 004/334] Turn off pre-commit's automated multiprocessing for flake8 flake8 internally implements multiprocessing, disabling pre-commit's improves performance --- .pre-commit-hooks.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 51577830..bd1b6736 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -136,6 +136,7 @@ entry: flake8 language: python types: [python] + require_serial: true - id: forbid-new-submodules name: Forbid new submodules language: python From c9f7b813e37048bfd75b404b800f5216350e78cc Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 29 Jan 2019 22:09:54 -0800 Subject: [PATCH 005/334] Add W504 to ignored autopep8 rules Committed via https://github.com/asottile/all-repos --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index a4be8bfa..c131e6f0 100644 --- a/tox.ini +++ b/tox.ini @@ -21,4 +21,4 @@ commands = max-line-length=131 [pep8] -ignore=E265,E501 +ignore=E265,E501,W504 From 63cc3414e9ee076267973bebb18ad2033175ce0d Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 30 Jan 2019 00:15:11 -0800 Subject: [PATCH 006/334] Updates for flake8 3.7 --- .pre-commit-config.yaml | 9 ++++++--- pre_commit_hooks/pretty_format_json.py | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 74f4c123..8bd0fdc5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,22 +11,25 @@ repos: - id: debug-statements - id: name-tests-test - id: requirements-txt-fixer +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.7.1 + hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-autopep8 rev: v1.4.3 hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v1.13.0 + rev: v1.14.2 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports - rev: v1.3.4 + rev: v1.3.5 hooks: - id: reorder-python-imports language_version: python2.7 - repo: https://github.com/asottile/pyupgrade - rev: v1.11.0 + rev: v1.11.1 hooks: - id: pyupgrade - repo: https://github.com/asottile/add-trailing-comma diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index fb1c487f..363037e2 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -42,7 +42,6 @@ def parse_num_to_int(s): def parse_topkeys(s): - # type: (str) -> array return s.split(',') From 030bfac7e40b0c009d234c3d6a2ef2baf9dede5a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 31 Jan 2019 19:19:10 -0800 Subject: [PATCH 007/334] Apply typing to all of pre-commit-hooks --- .gitignore | 9 +--- .pre-commit-config.yaml | 7 ++- .travis.yml | 4 +- get-git-lfs.py | 11 ++-- mypy.ini | 12 +++++ pre_commit_hooks/autopep8_wrapper.py | 2 +- pre_commit_hooks/check_added_large_files.py | 9 +++- pre_commit_hooks/check_ast.py | 6 ++- pre_commit_hooks/check_builtin_literals.py | 34 +++++++----- pre_commit_hooks/check_byte_order_marker.py | 4 +- pre_commit_hooks/check_case_conflict.py | 10 ++-- pre_commit_hooks/check_docstring_first.py | 5 +- .../check_executables_have_shebangs.py | 10 +++- pre_commit_hooks/check_json.py | 6 ++- pre_commit_hooks/check_merge_conflict.py | 9 ++-- pre_commit_hooks/check_symlinks.py | 6 ++- pre_commit_hooks/check_vcs_permalinks.py | 6 ++- pre_commit_hooks/check_xml.py | 10 ++-- pre_commit_hooks/check_yaml.py | 14 +++-- pre_commit_hooks/debug_statement_hook.py | 17 +++--- pre_commit_hooks/detect_aws_credentials.py | 16 ++++-- pre_commit_hooks/detect_private_key.py | 6 ++- pre_commit_hooks/end_of_file_fixer.py | 9 ++-- pre_commit_hooks/file_contents_sorter.py | 7 ++- pre_commit_hooks/fix_encoding_pragma.py | 20 ++++--- pre_commit_hooks/forbid_new_submodules.py | 5 +- pre_commit_hooks/mixed_line_ending.py | 11 ++-- pre_commit_hooks/no_commit_to_branch.py | 7 ++- pre_commit_hooks/pretty_format_json.py | 20 ++++--- pre_commit_hooks/requirements_txt_fixer.py | 30 +++++++---- pre_commit_hooks/sort_simple_yaml.py | 15 ++++-- pre_commit_hooks/string_fixer.py | 37 ++++++++----- pre_commit_hooks/tests_should_end_in_test.py | 10 ++-- pre_commit_hooks/trailing_whitespace_fixer.py | 8 +-- pre_commit_hooks/util.py | 12 +++-- setup.py | 23 ++++---- testing/resources/bad_json_latin1.nonjson | 0 testing/resources/builtin_constructors.py | 17 ------ testing/resources/builtin_literals.py | 7 --- tests/check_ast_test.py | 6 +-- tests/check_builtin_literals_test.py | 54 ++++++++++++++----- tests/check_json_test.py | 6 +-- tests/check_merge_conflict_test.py | 14 ++--- tests/check_symlinks_test.py | 10 ++-- tests/check_xml_test.py | 6 +-- tests/check_yaml_test.py | 24 ++++----- tests/detect_private_key_test.py | 6 +-- tests/end_of_file_fixer_test.py | 4 +- tests/no_commit_to_branch_test.py | 8 +-- tests/pretty_format_json_test.py | 34 ++++++------ tests/requirements_txt_fixer_test.py | 6 +-- tests/sort_simple_yaml_test.py | 4 +- tests/tests_should_end_in_test_test.py | 28 +++++----- tox.ini | 2 +- 54 files changed, 400 insertions(+), 263 deletions(-) create mode 100644 mypy.ini mode change 100755 => 100644 testing/resources/bad_json_latin1.nonjson delete mode 100644 testing/resources/builtin_constructors.py delete mode 100644 testing/resources/builtin_literals.py diff --git a/.gitignore b/.gitignore index c00e966c..32c2fec0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,11 @@ *.egg-info -*.iml *.py[co] .*.sw[a-z] -.pytest_cache .coverage -.idea -.project -.pydevproject .tox .venv.touch +/.mypy_cache +/.pytest_cache /venv* coverage-html dist -# SublimeText project/workspace files -*.sublime-* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8bd0fdc5..49905378 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: rev: v1.3.5 hooks: - id: reorder-python-imports - language_version: python2.7 + language_version: python3 - repo: https://github.com/asottile/pyupgrade rev: v1.11.1 hooks: @@ -36,3 +36,8 @@ repos: rev: v0.7.1 hooks: - id: add-trailing-comma +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.660 + hooks: + - id: mypy + language_version: python3 diff --git a/.travis.yml b/.travis.yml index 477b5c4b..fa16ccef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: xenial language: python matrix: include: # These should match the tox env list @@ -6,9 +7,8 @@ matrix: python: 3.6 - env: TOXENV=py37 python: 3.7 - dist: xenial - env: TOXENV=pypy - python: pypy-5.7.1 + python: pypy2.7-5.10.0 install: pip install coveralls tox script: tox before_install: diff --git a/get-git-lfs.py b/get-git-lfs.py index 48dd31eb..4b09cac6 100755 --- a/get-git-lfs.py +++ b/get-git-lfs.py @@ -4,7 +4,9 @@ import os.path import shutil import tarfile -from urllib.request import urlopen +import urllib.request +from typing import cast +from typing import IO DOWNLOAD_PATH = ( 'https://github.com/github/git-lfs/releases/download/' @@ -15,7 +17,7 @@ DEST_DIR = os.path.dirname(DEST_PATH) -def main(): +def main(): # type: () -> int if ( os.path.exists(DEST_PATH) and os.path.isfile(DEST_PATH) and @@ -27,12 +29,13 @@ def main(): shutil.rmtree(DEST_DIR, ignore_errors=True) os.makedirs(DEST_DIR, exist_ok=True) - contents = io.BytesIO(urlopen(DOWNLOAD_PATH).read()) + contents = io.BytesIO(urllib.request.urlopen(DOWNLOAD_PATH).read()) with tarfile.open(fileobj=contents) as tar: - with tar.extractfile(PATH_IN_TAR) as src_file: + with cast(IO[bytes], tar.extractfile(PATH_IN_TAR)) as src_file: with open(DEST_PATH, 'wb') as dest_file: shutil.copyfileobj(src_file, dest_file) os.chmod(DEST_PATH, 0o755) + return 0 if __name__ == '__main__': diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000..ee62c89f --- /dev/null +++ b/mypy.ini @@ -0,0 +1,12 @@ +[mypy] +check_untyped_defs = true +disallow_any_generics = true +disallow_incomplete_defs = true +disallow_untyped_defs = true +no_implicit_optional = true + +[mypy-testing.*] +disallow_untyped_defs = false + +[mypy-tests.*] +disallow_untyped_defs = false diff --git a/pre_commit_hooks/autopep8_wrapper.py b/pre_commit_hooks/autopep8_wrapper.py index 9951924d..8b69a049 100644 --- a/pre_commit_hooks/autopep8_wrapper.py +++ b/pre_commit_hooks/autopep8_wrapper.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals -def main(argv=None): +def main(): # type: () -> int raise SystemExit( 'autopep8-wrapper is deprecated. Instead use autopep8 directly via ' 'https://github.com/pre-commit/mirrors-autopep8', diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index 2d06706d..be394989 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -7,13 +7,17 @@ import json import math import os +from typing import Iterable +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 CalledProcessError from pre_commit_hooks.util import cmd_output -def lfs_files(): +def lfs_files(): # type: () -> Set[str] try: # Introduced in git-lfs 2.2.0, first working in 2.2.1 lfs_ret = cmd_output('git', 'lfs', 'status', '--json') @@ -24,6 +28,7 @@ def lfs_files(): def find_large_added_files(filenames, maxkb): + # type: (Iterable[str], int) -> int # Find all added files that are also in the list of files pre-commit tells # us about filenames = (added_files() & set(filenames)) - lfs_files() @@ -38,7 +43,7 @@ def find_large_added_files(filenames, maxkb): return retv -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 ded65e46..0df35407 100644 --- a/pre_commit_hooks/check_ast.py +++ b/pre_commit_hooks/check_ast.py @@ -7,9 +7,11 @@ import platform import sys import traceback +from typing import Optional +from typing import Sequence -def check_ast(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) @@ -34,4 +36,4 @@ def check_ast(argv=None): if __name__ == '__main__': - exit(check_ast()) + exit(main()) diff --git a/pre_commit_hooks/check_builtin_literals.py b/pre_commit_hooks/check_builtin_literals.py index 4a4b9ce3..874c68c5 100644 --- a/pre_commit_hooks/check_builtin_literals.py +++ b/pre_commit_hooks/check_builtin_literals.py @@ -4,6 +4,10 @@ import ast import collections import sys +from typing import List +from typing import Optional +from typing import Sequence +from typing import Set BUILTIN_TYPES = { @@ -22,14 +26,17 @@ class BuiltinTypeVisitor(ast.NodeVisitor): def __init__(self, ignore=None, allow_dict_kwargs=True): - self.builtin_type_calls = [] + # type: (Optional[Sequence[str]], bool) -> None + self.builtin_type_calls = [] # type: List[BuiltinTypeCall] self.ignore = set(ignore) if ignore else set() self.allow_dict_kwargs = allow_dict_kwargs - def _check_dict_call(self, node): + def _check_dict_call(self, node): # type: (ast.Call) -> bool + return self.allow_dict_kwargs and (getattr(node, 'kwargs', None) or getattr(node, 'keywords', None)) - def visit_Call(self, node): + def visit_Call(self, node): # type: (ast.Call) -> None + if not isinstance(node.func, ast.Name): # Ignore functions that are object attributes (`foo.bar()`). # Assume that if the user calls `builtins.list()`, they know what @@ -47,6 +54,7 @@ def visit_Call(self, node): def check_file_for_builtin_type_constructors(filename, ignore=None, allow_dict_kwargs=True): + # type: (str, Optional[Sequence[str]], bool) -> List[BuiltinTypeCall] with open(filename, 'rb') as f: tree = ast.parse(f.read(), filename=filename) visitor = BuiltinTypeVisitor(ignore=ignore, allow_dict_kwargs=allow_dict_kwargs) @@ -54,24 +62,22 @@ def check_file_for_builtin_type_constructors(filename, ignore=None, allow_dict_k return visitor.builtin_type_calls -def parse_args(argv): - def parse_ignore(value): - return set(value.split(',')) +def parse_ignore(value): # type: (str) -> Set[str] + return set(value.split(',')) + +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') parser.add_argument('--ignore', type=parse_ignore, default=set()) - allow_dict_kwargs = parser.add_mutually_exclusive_group(required=False) - allow_dict_kwargs.add_argument('--allow-dict-kwargs', action='store_true') - allow_dict_kwargs.add_argument('--no-allow-dict-kwargs', dest='allow_dict_kwargs', action='store_false') - allow_dict_kwargs.set_defaults(allow_dict_kwargs=True) - - return parser.parse_args(argv) + mutex = parser.add_mutually_exclusive_group(required=False) + mutex.add_argument('--allow-dict-kwargs', action='store_true') + mutex.add_argument('--no-allow-dict-kwargs', dest='allow_dict_kwargs', action='store_false') + mutex.set_defaults(allow_dict_kwargs=True) + args = parser.parse_args(argv) -def main(argv=None): - args = parse_args(argv) rc = 0 for filename in args.filenames: calls = check_file_for_builtin_type_constructors( diff --git a/pre_commit_hooks/check_byte_order_marker.py b/pre_commit_hooks/check_byte_order_marker.py index 1541b302..10667c33 100644 --- a/pre_commit_hooks/check_byte_order_marker.py +++ b/pre_commit_hooks/check_byte_order_marker.py @@ -3,9 +3,11 @@ from __future__ import unicode_literals import argparse +from typing import Optional +from typing import Sequence -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 0f782965..e343d61f 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -3,16 +3,20 @@ from __future__ import unicode_literals import argparse +from typing import Iterable +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): +def lower_set(iterable): # type: (Iterable[str]) -> Set[str] return {x.lower() for x in iterable} -def find_conflicting_filenames(filenames): +def find_conflicting_filenames(filenames): # type: (Sequence[str]) -> int repo_files = set(cmd_output('git', 'ls-files').splitlines()) relevant_files = set(filenames) | added_files() repo_files -= relevant_files @@ -41,7 +45,7 @@ def find_conflicting_filenames(filenames): return retv -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 9988378a..f4639f17 100644 --- a/pre_commit_hooks/check_docstring_first.py +++ b/pre_commit_hooks/check_docstring_first.py @@ -5,6 +5,8 @@ import argparse import io import tokenize +from typing import Optional +from typing import Sequence NON_CODE_TOKENS = frozenset(( @@ -13,6 +15,7 @@ def check_docstring_first(src, filename=''): + # type: (str, str) -> int """Returns nonzero if the source has what looks like a docstring that is not at the beginning of the source. @@ -50,7 +53,7 @@ def check_docstring_first(src, filename=''): return 0 -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 89ac6e5b..c936a5dd 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -6,9 +6,11 @@ import argparse import pipes import sys +from typing import Optional +from typing import Sequence -def check_has_shebang(path): +def check_has_shebang(path): # type: (str) -> int with open(path, 'rb') as f: first_bytes = f.read(2) @@ -27,7 +29,7 @@ def check_has_shebang(path): return 0 -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) @@ -38,3 +40,7 @@ def main(argv=None): retv |= check_has_shebang(filename) return retv + + +if __name__ == '__main__': + exit(main()) diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py index b403f4b2..b9393508 100644 --- a/pre_commit_hooks/check_json.py +++ b/pre_commit_hooks/check_json.py @@ -4,9 +4,11 @@ import io import json import sys +from typing import Optional +from typing import Sequence -def check_json(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='JSON filenames to check.') args = parser.parse_args(argv) @@ -22,4 +24,4 @@ def check_json(argv=None): if __name__ == '__main__': - sys.exit(check_json()) + sys.exit(main()) diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index 6db5efe9..74e4ae17 100644 --- a/pre_commit_hooks/check_merge_conflict.py +++ b/pre_commit_hooks/check_merge_conflict.py @@ -2,6 +2,9 @@ import argparse import os.path +from typing import Optional +from typing import Sequence + CONFLICT_PATTERNS = [ b'<<<<<<< ', @@ -12,7 +15,7 @@ WARNING_MSG = 'Merge conflict string "{0}" found in {1}:{2}' -def is_in_merge(): +def is_in_merge(): # type: () -> int return ( os.path.exists(os.path.join('.git', 'MERGE_MSG')) and ( @@ -23,7 +26,7 @@ def is_in_merge(): ) -def detect_merge_conflict(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') parser.add_argument('--assume-in-merge', action='store_true') @@ -47,4 +50,4 @@ def detect_merge_conflict(argv=None): if __name__ == '__main__': - exit(detect_merge_conflict()) + exit(main()) diff --git a/pre_commit_hooks/check_symlinks.py b/pre_commit_hooks/check_symlinks.py index 010c8715..736bf99c 100644 --- a/pre_commit_hooks/check_symlinks.py +++ b/pre_commit_hooks/check_symlinks.py @@ -4,9 +4,11 @@ import argparse import os.path +from typing import Optional +from typing import Sequence -def check_symlinks(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser(description='Checks for broken symlinks.') parser.add_argument('filenames', nargs='*', help='Filenames to check') args = parser.parse_args(argv) @@ -25,4 +27,4 @@ def check_symlinks(argv=None): if __name__ == '__main__': - exit(check_symlinks()) + exit(main()) diff --git a/pre_commit_hooks/check_vcs_permalinks.py b/pre_commit_hooks/check_vcs_permalinks.py index f0dcf5b6..f6e2a7d5 100644 --- a/pre_commit_hooks/check_vcs_permalinks.py +++ b/pre_commit_hooks/check_vcs_permalinks.py @@ -5,6 +5,8 @@ import argparse import re import sys +from typing import Optional +from typing import Sequence GITHUB_NON_PERMALINK = re.compile( @@ -12,7 +14,7 @@ ) -def _check_filename(filename): +def _check_filename(filename): # type: (str) -> int retv = 0 with open(filename, 'rb') as f: for i, line in enumerate(f, 1): @@ -24,7 +26,7 @@ def _check_filename(filename): return retv -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py index a4c11a59..66e10bac 100644 --- a/pre_commit_hooks/check_xml.py +++ b/pre_commit_hooks/check_xml.py @@ -5,10 +5,12 @@ import argparse import io import sys -import xml.sax +import xml.sax.handler +from typing import Optional +from typing import Sequence -def check_xml(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='XML filenames to check.') args = parser.parse_args(argv) @@ -17,7 +19,7 @@ def check_xml(argv=None): for filename in args.filenames: try: with io.open(filename, 'rb') as xml_file: - xml.sax.parse(xml_file, xml.sax.ContentHandler()) + xml.sax.parse(xml_file, xml.sax.handler.ContentHandler()) except xml.sax.SAXException as exc: print('{}: Failed to xml parse ({})'.format(filename, exc)) retval = 1 @@ -25,4 +27,4 @@ def check_xml(argv=None): if __name__ == '__main__': - sys.exit(check_xml()) + sys.exit(main()) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 208737f1..b638684b 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -3,22 +3,26 @@ import argparse import collections import sys +from typing import Any +from typing import Generator +from typing import Optional +from typing import Sequence import ruamel.yaml yaml = ruamel.yaml.YAML(typ='safe') -def _exhaust(gen): +def _exhaust(gen): # type: (Generator[str, None, None]) -> None for _ in gen: pass -def _parse_unsafe(*args, **kwargs): +def _parse_unsafe(*args, **kwargs): # type: (*Any, **Any) -> None _exhaust(yaml.parse(*args, **kwargs)) -def _load_all(*args, **kwargs): +def _load_all(*args, **kwargs): # type: (*Any, **Any) -> None _exhaust(yaml.load_all(*args, **kwargs)) @@ -31,7 +35,7 @@ def _load_all(*args, **kwargs): } -def check_yaml(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument( '-m', '--multi', '--allow-multiple-documents', action='store_true', @@ -63,4 +67,4 @@ def check_yaml(argv=None): if __name__ == '__main__': - sys.exit(check_yaml()) + sys.exit(main()) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 5d32277a..02dd3b29 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -5,6 +5,9 @@ import ast import collections import traceback +from typing import List +from typing import Optional +from typing import Sequence DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb'} @@ -12,21 +15,21 @@ class DebugStatementParser(ast.NodeVisitor): - def __init__(self): - self.breakpoints = [] + def __init__(self): # type: () -> None + self.breakpoints = [] # type: List[Debug] - def visit_Import(self, node): + def visit_Import(self, node): # type: (ast.Import) -> None for name in node.names: if name.name in DEBUG_STATEMENTS: st = Debug(node.lineno, node.col_offset, name.name, 'imported') self.breakpoints.append(st) - def visit_ImportFrom(self, node): + def visit_ImportFrom(self, node): # type: (ast.ImportFrom) -> None if node.module in DEBUG_STATEMENTS: st = Debug(node.lineno, node.col_offset, node.module, 'imported') self.breakpoints.append(st) - def visit_Call(self, node): + def visit_Call(self, node): # type: (ast.Call) -> None """python3.7+ breakpoint()""" if isinstance(node.func, ast.Name) and node.func.id == 'breakpoint': st = Debug(node.lineno, node.col_offset, node.func.id, 'called') @@ -34,7 +37,7 @@ def visit_Call(self, node): self.generic_visit(node) -def check_file(filename): +def check_file(filename): # type: (str) -> int try: with open(filename, 'rb') as f: ast_obj = ast.parse(f.read(), filename=filename) @@ -58,7 +61,7 @@ def check_file(filename): return int(bool(visitor.breakpoints)) -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to run') args = parser.parse_args(argv) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index ecd9d40d..3c87d117 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -3,11 +3,16 @@ import argparse import os +from typing import Dict +from typing import List +from typing import Optional +from typing import Sequence +from typing import Set from six.moves import configparser -def get_aws_credential_files_from_env(): +def get_aws_credential_files_from_env(): # type: () -> Set[str] """Extract credential file paths from environment variables.""" files = set() for env_var in ( @@ -19,7 +24,7 @@ def get_aws_credential_files_from_env(): return files -def get_aws_secrets_from_env(): +def get_aws_secrets_from_env(): # type: () -> Set[str] """Extract AWS secrets from environment variables.""" keys = set() for env_var in ( @@ -30,7 +35,7 @@ def get_aws_secrets_from_env(): return keys -def get_aws_secrets_from_file(credentials_file): +def get_aws_secrets_from_file(credentials_file): # type: (str) -> Set[str] """Extract AWS secrets from configuration files. Read an ini-style configuration file and return a set with all found AWS @@ -62,6 +67,7 @@ def get_aws_secrets_from_file(credentials_file): def check_file_for_aws_keys(filenames, keys): + # type: (Sequence[str], Set[str]) -> List[Dict[str, str]] """Check if files contain AWS secrets. Return a list of all files containing AWS secrets and keys found, with all @@ -82,7 +88,7 @@ def check_file_for_aws_keys(filenames, keys): return bad_files -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='+', help='Filenames to run') parser.add_argument( @@ -111,7 +117,7 @@ def main(argv=None): # of files to to gather AWS secrets from. credential_files |= get_aws_credential_files_from_env() - keys = set() + keys = set() # type: Set[str] 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 c8ee9611..d31957de 100644 --- a/pre_commit_hooks/detect_private_key.py +++ b/pre_commit_hooks/detect_private_key.py @@ -2,6 +2,8 @@ import argparse import sys +from typing import Optional +from typing import Sequence BLACKLIST = [ b'BEGIN RSA PRIVATE KEY', @@ -15,7 +17,7 @@ ] -def detect_private_key(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to check') args = parser.parse_args(argv) @@ -37,4 +39,4 @@ def detect_private_key(argv=None): if __name__ == '__main__': - sys.exit(detect_private_key()) + sys.exit(main()) diff --git a/pre_commit_hooks/end_of_file_fixer.py b/pre_commit_hooks/end_of_file_fixer.py index 5ab1b7b0..4e77c945 100644 --- a/pre_commit_hooks/end_of_file_fixer.py +++ b/pre_commit_hooks/end_of_file_fixer.py @@ -4,9 +4,12 @@ import argparse import os import sys +from typing import IO +from typing import Optional +from typing import Sequence -def fix_file(file_obj): +def fix_file(file_obj): # type: (IO[bytes]) -> int # Test for newline at end of file # Empty files will throw IOError here try: @@ -49,7 +52,7 @@ def fix_file(file_obj): return 0 -def end_of_file_fixer(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -68,4 +71,4 @@ def end_of_file_fixer(argv=None): if __name__ == '__main__': - sys.exit(end_of_file_fixer()) + sys.exit(main()) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index fe7f7ee3..6f13c98a 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -12,12 +12,15 @@ from __future__ import print_function import argparse +from typing import IO +from typing import Optional +from typing import Sequence PASS = 0 FAIL = 1 -def sort_file_contents(f): +def sort_file_contents(f): # type: (IO[bytes]) -> int before = list(f) after = sorted([line.strip(b'\n\r') for line in before if line.strip()]) @@ -33,7 +36,7 @@ def sort_file_contents(f): return FAIL -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='+', help='Files to sort') args = parser.parse_args(argv) diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index 3bf234ed..b0b5c8ec 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -4,11 +4,15 @@ import argparse import collections +from typing import IO +from typing import Optional +from typing import Sequence +from typing import Union DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-\n' -def has_coding(line): +def has_coding(line): # type: (bytes) -> bool if not line.strip(): return False return ( @@ -33,15 +37,16 @@ class ExpectedContents(collections.namedtuple( __slots__ = () @property - def has_any_pragma(self): + def has_any_pragma(self): # type: () -> bool return self.pragma_status is not False - def is_expected_pragma(self, remove): + def is_expected_pragma(self, remove): # type: (bool) -> bool expected_pragma_status = not remove return self.pragma_status is expected_pragma_status def _get_expected_contents(first_line, second_line, rest, expected_pragma): + # type: (bytes, bytes, bytes, bytes) -> ExpectedContents if first_line.startswith(b'#!'): shebang = first_line potential_coding = second_line @@ -51,7 +56,7 @@ def _get_expected_contents(first_line, second_line, rest, expected_pragma): rest = second_line + rest if potential_coding == expected_pragma: - pragma_status = True + pragma_status = True # type: Optional[bool] elif has_coding(potential_coding): pragma_status = None else: @@ -64,6 +69,7 @@ def _get_expected_contents(first_line, second_line, rest, expected_pragma): def fix_encoding_pragma(f, remove=False, expected_pragma=DEFAULT_PRAGMA): + # type: (IO[bytes], bool, bytes) -> int expected = _get_expected_contents( f.readline(), f.readline(), f.read(), expected_pragma, ) @@ -93,17 +99,17 @@ def fix_encoding_pragma(f, remove=False, expected_pragma=DEFAULT_PRAGMA): return 1 -def _normalize_pragma(pragma): +def _normalize_pragma(pragma): # type: (Union[bytes, str]) -> bytes if not isinstance(pragma, bytes): pragma = pragma.encode('UTF-8') return pragma.rstrip() + b'\n' -def _to_disp(pragma): +def _to_disp(pragma): # type: (bytes) -> str return pragma.decode().rstrip() -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser('Fixes the encoding pragma of python files') parser.add_argument('filenames', nargs='*', help='Filenames to fix') parser.add_argument( diff --git a/pre_commit_hooks/forbid_new_submodules.py b/pre_commit_hooks/forbid_new_submodules.py index c9464cf7..bdbd6f7f 100644 --- a/pre_commit_hooks/forbid_new_submodules.py +++ b/pre_commit_hooks/forbid_new_submodules.py @@ -2,10 +2,13 @@ from __future__ import print_function from __future__ import unicode_literals +from typing import Optional +from typing import Sequence + from pre_commit_hooks.util import cmd_output -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int # `argv` is ignored, pre-commit will send us a list of files that we # don't care about added_diff = cmd_output( diff --git a/pre_commit_hooks/mixed_line_ending.py b/pre_commit_hooks/mixed_line_ending.py index e35a65c9..90aef035 100644 --- a/pre_commit_hooks/mixed_line_ending.py +++ b/pre_commit_hooks/mixed_line_ending.py @@ -4,6 +4,9 @@ import argparse import collections +from typing import Dict +from typing import Optional +from typing import Sequence CRLF = b'\r\n' @@ -14,7 +17,7 @@ FIX_TO_LINE_ENDING = {'cr': CR, 'crlf': CRLF, 'lf': LF} -def _fix(filename, contents, ending): +def _fix(filename, contents, ending): # type: (str, bytes, bytes) -> None new_contents = b''.join( line.rstrip(b'\r\n') + ending for line in contents.splitlines(True) ) @@ -22,11 +25,11 @@ def _fix(filename, contents, ending): f.write(new_contents) -def fix_filename(filename, fix): +def fix_filename(filename, fix): # type: (str, str) -> int with open(filename, 'rb') as f: contents = f.read() - counts = collections.defaultdict(int) + counts = collections.defaultdict(int) # type: Dict[bytes, int] for line in contents.splitlines(True): for ending in ALL_ENDINGS: @@ -63,7 +66,7 @@ def fix_filename(filename, fix): return other_endings -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 fdd146bc..6b68c915 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -1,12 +1,15 @@ from __future__ import print_function import argparse +from typing import Optional +from typing import Sequence +from typing import Set from pre_commit_hooks.util import CalledProcessError from pre_commit_hooks.util import cmd_output -def is_on_branch(protected): +def is_on_branch(protected): # type: (Set[str]) -> bool try: branch = cmd_output('git', 'symbolic-ref', 'HEAD') except CalledProcessError: @@ -15,7 +18,7 @@ def is_on_branch(protected): return '/'.join(chunks[2:]) in protected -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 363037e2..de7f8d71 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -5,12 +5,20 @@ import json import sys from collections import OrderedDict +from typing import List +from typing import Mapping +from typing import Optional +from typing import Sequence +from typing import Tuple +from typing import Union from six import text_type -def _get_pretty_format(contents, indent, ensure_ascii=True, sort_keys=True, top_keys=[]): +def _get_pretty_format(contents, indent, ensure_ascii=True, sort_keys=True, top_keys=()): + # type: (str, str, bool, bool, Sequence[str]) -> str def pairs_first(pairs): + # type: (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] @@ -27,13 +35,13 @@ def pairs_first(pairs): return text_type(json_pretty) + '\n' -def _autofix(filename, new_contents): +def _autofix(filename, new_contents): # type: (str, str) -> None print('Fixing file {}'.format(filename)) with io.open(filename, 'w', encoding='UTF-8') as f: f.write(new_contents) -def parse_num_to_int(s): +def parse_num_to_int(s): # type: (str) -> Union[int, str] """Convert string numbers to int, leaving strings as is.""" try: return int(s) @@ -41,11 +49,11 @@ def parse_num_to_int(s): return s -def parse_topkeys(s): +def parse_topkeys(s): # type: (str) -> List[str] return s.split(',') -def pretty_format_json(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument( '--autofix', @@ -117,4 +125,4 @@ def pretty_format_json(argv=None): if __name__ == '__main__': - sys.exit(pretty_format_json()) + sys.exit(main()) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 6dcf8d09..3f85a17a 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -1,6 +1,10 @@ from __future__ import print_function import argparse +from typing import IO +from typing import List +from typing import Optional +from typing import Sequence PASS = 0 @@ -9,21 +13,23 @@ class Requirement(object): - def __init__(self): + def __init__(self): # type: () -> None super(Requirement, self).__init__() - self.value = None - self.comments = [] + self.value = None # type: Optional[bytes] + self.comments = [] # type: List[bytes] @property - def name(self): + def name(self): # type: () -> bytes + assert self.value is not None, self.value if self.value.startswith(b'-e '): return self.value.lower().partition(b'=')[-1] return self.value.lower().partition(b'==')[0] - def __lt__(self, requirement): + def __lt__(self, requirement): # type: (Requirement) -> int # \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 if self.value == b'\n': return True elif requirement.value == b'\n': @@ -32,10 +38,10 @@ def __lt__(self, requirement): return self.name < requirement.name -def fix_requirements(f): - requirements = [] +def fix_requirements(f): # type: (IO[bytes]) -> int + requirements = [] # type: List[Requirement] before = tuple(f) - after = [] + after = [] # type: List[bytes] before_string = b''.join(before) @@ -46,6 +52,7 @@ def fix_requirements(f): for line in before: # If the most recent requirement object has a value, then it's # time to start building the next requirement object. + if not len(requirements) or requirements[-1].value is not None: requirements.append(Requirement()) @@ -78,6 +85,7 @@ def fix_requirements(f): for requirement in sorted(requirements): after.extend(requirement.comments) + assert requirement.value, requirement.value after.append(requirement.value) after.extend(rest) @@ -92,7 +100,7 @@ def fix_requirements(f): return FAIL -def fix_requirements_txt(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -109,3 +117,7 @@ def fix_requirements_txt(argv=None): retv |= ret_for_file return retv + + +if __name__ == '__main__': + exit(main()) diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py index 7afae917..3c8ef165 100755 --- a/pre_commit_hooks/sort_simple_yaml.py +++ b/pre_commit_hooks/sort_simple_yaml.py @@ -21,12 +21,15 @@ from __future__ import print_function import argparse +from typing import List +from typing import Optional +from typing import Sequence QUOTES = ["'", '"'] -def sort(lines): +def sort(lines): # type: (List[str]) -> List[str] """Sort a YAML file in alphabetical order, keeping blocks together. :param lines: array of strings (without newlines) @@ -44,7 +47,7 @@ def sort(lines): return new_lines -def parse_block(lines, header=False): +def parse_block(lines, header=False): # type: (List[str], bool) -> 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 +63,7 @@ def parse_block(lines, header=False): return block_lines -def parse_blocks(lines): +def parse_blocks(lines): # type: (List[str]) -> List[List[str]] """Parse and return all possible blocks, popping off the start of `lines`. :param lines: list of lines @@ -77,7 +80,7 @@ def parse_blocks(lines): return blocks -def first_key(lines): +def first_key(lines): # type: (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 @@ -95,9 +98,11 @@ def first_key(lines): if any(line.startswith(quote) for quote in QUOTES): return line[1:] return line + else: + return '' # not actually reached in reality -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 c432682f..a5ea1ea9 100644 --- a/pre_commit_hooks/string_fixer.py +++ b/pre_commit_hooks/string_fixer.py @@ -4,34 +4,39 @@ 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]*"') -double_quote_starts = tuple(s for s in tokenize.single_quoted if '"' in s) - -def handle_match(token_text): +def handle_match(token_text): # type: (str) -> str if '"""' in token_text or "'''" in token_text: return token_text - for double_quote_start in double_quote_starts: - if token_text.startswith(double_quote_start): - meat = token_text[len(double_quote_start):-1] - if '"' in meat or "'" in meat: - break - return double_quote_start.replace('"', "'") + meat + "'" - return token_text + match = START_QUOTE_RE.match(token_text) + if match is not None: + meat = token_text[match.end():-1] + if '"' in meat or "'" in meat: + return token_text + else: + return match.group().replace('"', "'") + meat + "'" + else: + return token_text -def get_line_offsets_by_line_no(src): +def get_line_offsets_by_line_no(src): # type: (str) -> List[int] # Padded so we can index with line number - offsets = [None, 0] + offsets = [-1, 0] for line in src.splitlines(): offsets.append(offsets[-1] + len(line) + 1) return offsets -def fix_strings(filename): +def fix_strings(filename): # type: (str) -> int with io.open(filename, encoding='UTF-8') as f: contents = f.read() line_offsets = get_line_offsets_by_line_no(contents) @@ -60,7 +65,7 @@ def fix_strings(filename): return 0 -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -74,3 +79,7 @@ def main(argv=None): retv |= return_value return retv + + +if __name__ == '__main__': + exit(main()) diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py index 9bea20db..7a1e7c04 100644 --- a/pre_commit_hooks/tests_should_end_in_test.py +++ b/pre_commit_hooks/tests_should_end_in_test.py @@ -1,12 +1,14 @@ from __future__ import print_function import argparse +import os.path import re import sys -from os.path import basename +from typing import Optional +from typing import Sequence -def validate_files(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') parser.add_argument( @@ -18,7 +20,7 @@ def validate_files(argv=None): retcode = 0 test_name_pattern = 'test.*.py' if args.django else '.*_test.py' for filename in args.filenames: - base = basename(filename) + base = os.path.basename(filename) if ( not re.match(test_name_pattern, base) and not base == '__init__.py' and @@ -35,4 +37,4 @@ def validate_files(argv=None): if __name__ == '__main__': - sys.exit(validate_files()) + sys.exit(main()) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 1b54fbd2..4fe7975e 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -3,9 +3,11 @@ import argparse import os import sys +from typing import Optional +from typing import Sequence -def _fix_file(filename, is_markdown): +def _fix_file(filename, is_markdown): # type: (str, bool) -> bool with open(filename, mode='rb') as file_processed: lines = file_processed.readlines() newlines = [_process_line(line, is_markdown) for line in lines] @@ -18,7 +20,7 @@ def _fix_file(filename, is_markdown): return False -def _process_line(line, is_markdown): +def _process_line(line, is_markdown): # type: (bytes, bool) -> bytes if line[-2:] == b'\r\n': eol = b'\r\n' elif line[-1:] == b'\n': @@ -31,7 +33,7 @@ def _process_line(line, is_markdown): return line.rstrip() + eol -def main(argv=None): +def main(argv=None): # type: (Optional[Sequence[str]]) -> 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 269b5537..5d1d11bd 100644 --- a/pre_commit_hooks/util.py +++ b/pre_commit_hooks/util.py @@ -3,23 +3,25 @@ from __future__ import unicode_literals import subprocess +from typing import Any +from typing import Set class CalledProcessError(RuntimeError): pass -def added_files(): +def added_files(): # type: () -> Set[str] return set(cmd_output( 'git', 'diff', '--staged', '--name-only', '--diff-filter=A', ).splitlines()) -def cmd_output(*cmd, **kwargs): +def cmd_output(*cmd, **kwargs): # type: (*str, **Any) -> str retcode = kwargs.pop('retcode', 0) - popen_kwargs = {'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE} - popen_kwargs.update(kwargs) - proc = subprocess.Popen(cmd, **popen_kwargs) + kwargs.setdefault('stdout', subprocess.PIPE) + kwargs.setdefault('stderr', subprocess.PIPE) + proc = subprocess.Popen(cmd, **kwargs) stdout, stderr = proc.communicate() stdout = stdout.decode('UTF-8') if stderr is not None: diff --git a/setup.py b/setup.py index 84892a7c..756500b2 100644 --- a/setup.py +++ b/setup.py @@ -28,35 +28,36 @@ 'ruamel.yaml>=0.15', 'six', ], + extras_require={':python_version<"3.5"': ['typing']}, entry_points={ 'console_scripts': [ 'autopep8-wrapper = pre_commit_hooks.autopep8_wrapper:main', 'check-added-large-files = pre_commit_hooks.check_added_large_files:main', - 'check-ast = pre_commit_hooks.check_ast:check_ast', + 'check-ast = pre_commit_hooks.check_ast:main', 'check-builtin-literals = pre_commit_hooks.check_builtin_literals:main', 'check-byte-order-marker = pre_commit_hooks.check_byte_order_marker:main', 'check-case-conflict = pre_commit_hooks.check_case_conflict:main', 'check-docstring-first = pre_commit_hooks.check_docstring_first:main', 'check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main', - 'check-json = pre_commit_hooks.check_json:check_json', - 'check-merge-conflict = pre_commit_hooks.check_merge_conflict:detect_merge_conflict', - 'check-symlinks = pre_commit_hooks.check_symlinks:check_symlinks', + 'check-json = pre_commit_hooks.check_json:main', + 'check-merge-conflict = pre_commit_hooks.check_merge_conflict:main', + 'check-symlinks = pre_commit_hooks.check_symlinks:main', 'check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main', - 'check-xml = pre_commit_hooks.check_xml:check_xml', - 'check-yaml = pre_commit_hooks.check_yaml:check_yaml', + 'check-xml = pre_commit_hooks.check_xml:main', + 'check-yaml = pre_commit_hooks.check_yaml:main', 'debug-statement-hook = pre_commit_hooks.debug_statement_hook:main', 'detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main', - 'detect-private-key = pre_commit_hooks.detect_private_key:detect_private_key', + 'detect-private-key = pre_commit_hooks.detect_private_key:main', 'double-quote-string-fixer = pre_commit_hooks.string_fixer:main', - 'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:end_of_file_fixer', + 'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:main', 'file-contents-sorter = pre_commit_hooks.file_contents_sorter:main', 'fix-encoding-pragma = pre_commit_hooks.fix_encoding_pragma:main', 'forbid-new-submodules = pre_commit_hooks.forbid_new_submodules:main', 'mixed-line-ending = pre_commit_hooks.mixed_line_ending:main', - 'name-tests-test = pre_commit_hooks.tests_should_end_in_test:validate_files', + 'name-tests-test = pre_commit_hooks.tests_should_end_in_test:main', 'no-commit-to-branch = pre_commit_hooks.no_commit_to_branch:main', - 'pretty-format-json = pre_commit_hooks.pretty_format_json:pretty_format_json', - 'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:fix_requirements_txt', + 'pretty-format-json = pre_commit_hooks.pretty_format_json:main', + 'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main', 'sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main', 'trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main', ], diff --git a/testing/resources/bad_json_latin1.nonjson b/testing/resources/bad_json_latin1.nonjson old mode 100755 new mode 100644 diff --git a/testing/resources/builtin_constructors.py b/testing/resources/builtin_constructors.py deleted file mode 100644 index 174a9e85..00000000 --- a/testing/resources/builtin_constructors.py +++ /dev/null @@ -1,17 +0,0 @@ -from six.moves import builtins - -c1 = complex() -d1 = dict() -f1 = float() -i1 = int() -l1 = list() -s1 = str() -t1 = tuple() - -c2 = builtins.complex() -d2 = builtins.dict() -f2 = builtins.float() -i2 = builtins.int() -l2 = builtins.list() -s2 = builtins.str() -t2 = builtins.tuple() diff --git a/testing/resources/builtin_literals.py b/testing/resources/builtin_literals.py deleted file mode 100644 index 8513b706..00000000 --- a/testing/resources/builtin_literals.py +++ /dev/null @@ -1,7 +0,0 @@ -c1 = 0j -d1 = {} -f1 = 0.0 -i1 = 0 -l1 = [] -s1 = '' -t1 = () diff --git a/tests/check_ast_test.py b/tests/check_ast_test.py index 64916ba4..c16f5fcc 100644 --- a/tests/check_ast_test.py +++ b/tests/check_ast_test.py @@ -1,15 +1,15 @@ from __future__ import absolute_import from __future__ import unicode_literals -from pre_commit_hooks.check_ast import check_ast +from pre_commit_hooks.check_ast import main from testing.util import get_resource_path def test_failing_file(): - ret = check_ast([get_resource_path('cannot_parse_ast.notpy')]) + ret = main([get_resource_path('cannot_parse_ast.notpy')]) assert ret == 1 def test_passing_file(): - ret = check_ast([__file__]) + ret = main([__file__]) assert ret == 0 diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py index 86b79e3b..d4ac30f8 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -5,7 +5,35 @@ from pre_commit_hooks.check_builtin_literals import BuiltinTypeCall from pre_commit_hooks.check_builtin_literals import BuiltinTypeVisitor from pre_commit_hooks.check_builtin_literals import main -from testing.util import get_resource_path + +BUILTIN_CONSTRUCTORS = '''\ +from six.moves import builtins + +c1 = complex() +d1 = dict() +f1 = float() +i1 = int() +l1 = list() +s1 = str() +t1 = tuple() + +c2 = builtins.complex() +d2 = builtins.dict() +f2 = builtins.float() +i2 = builtins.int() +l2 = builtins.list() +s2 = builtins.str() +t2 = builtins.tuple() +''' +BUILTIN_LITERALS = '''\ +c1 = 0j +d1 = {} +f1 = 0.0 +i1 = 0 +l1 = [] +s1 = '' +t1 = () +''' @pytest.fixture @@ -94,24 +122,26 @@ def test_dict_no_allow_kwargs_exprs(expression, calls): def test_ignore_constructors(): visitor = BuiltinTypeVisitor(ignore=('complex', 'dict', 'float', 'int', 'list', 'str', 'tuple')) - with open(get_resource_path('builtin_constructors.py'), 'rb') as f: - visitor.visit(ast.parse(f.read(), 'builtin_constructors.py')) + visitor.visit(ast.parse(BUILTIN_CONSTRUCTORS)) assert visitor.builtin_type_calls == [] -def test_failing_file(): - rc = main([get_resource_path('builtin_constructors.py')]) +def test_failing_file(tmpdir): + f = tmpdir.join('f.py') + f.write(BUILTIN_CONSTRUCTORS) + rc = main([f.strpath]) assert rc == 1 -def test_passing_file(): - rc = main([get_resource_path('builtin_literals.py')]) +def test_passing_file(tmpdir): + f = tmpdir.join('f.py') + f.write(BUILTIN_LITERALS) + rc = main([f.strpath]) assert rc == 0 -def test_failing_file_ignore_all(): - rc = main([ - '--ignore=complex,dict,float,int,list,str,tuple', - get_resource_path('builtin_constructors.py'), - ]) +def test_failing_file_ignore_all(tmpdir): + f = tmpdir.join('f.py') + f.write(BUILTIN_CONSTRUCTORS) + rc = main(['--ignore=complex,dict,float,int,list,str,tuple', f.strpath]) assert rc == 0 diff --git a/tests/check_json_test.py b/tests/check_json_test.py index 6ba26c14..6654ed10 100644 --- a/tests/check_json_test.py +++ b/tests/check_json_test.py @@ -1,6 +1,6 @@ import pytest -from pre_commit_hooks.check_json import check_json +from pre_commit_hooks.check_json import main from testing.util import get_resource_path @@ -11,8 +11,8 @@ ('ok_json.json', 0), ), ) -def test_check_json(capsys, filename, expected_retval): - ret = check_json([get_resource_path(filename)]) +def test_main(capsys, filename, expected_retval): + ret = main([get_resource_path(filename)]) assert ret == expected_retval if expected_retval == 1: stdout, _ = capsys.readouterr() diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index b04c70e0..50e389c9 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -6,7 +6,7 @@ import pytest -from pre_commit_hooks.check_merge_conflict import detect_merge_conflict +from pre_commit_hooks.check_merge_conflict import main from pre_commit_hooks.util import cmd_output from testing.util import get_resource_path @@ -102,7 +102,7 @@ def repository_pending_merge(tmpdir): @pytest.mark.usefixtures('f1_is_a_conflict_file') def test_merge_conflicts_git(): - assert detect_merge_conflict(['f1']) == 1 + assert main(['f1']) == 1 @pytest.mark.parametrize( @@ -110,7 +110,7 @@ def test_merge_conflicts_git(): ) def test_merge_conflicts_failing(contents, repository_pending_merge): repository_pending_merge.join('f2').write_binary(contents) - assert detect_merge_conflict(['f2']) == 1 + assert main(['f2']) == 1 @pytest.mark.parametrize( @@ -118,22 +118,22 @@ def test_merge_conflicts_failing(contents, repository_pending_merge): ) def test_merge_conflicts_ok(contents, f1_is_a_conflict_file): f1_is_a_conflict_file.join('f1').write_binary(contents) - assert detect_merge_conflict(['f1']) == 0 + assert main(['f1']) == 0 @pytest.mark.usefixtures('f1_is_a_conflict_file') def test_ignores_binary_files(): shutil.copy(get_resource_path('img1.jpg'), 'f1') - assert detect_merge_conflict(['f1']) == 0 + assert main(['f1']) == 0 def test_does_not_care_when_not_in_a_merge(tmpdir): f = tmpdir.join('README.md') f.write_binary(b'problem\n=======\n') - assert detect_merge_conflict([str(f.realpath())]) == 0 + assert main([str(f.realpath())]) == 0 def test_care_when_assumed_merge(tmpdir): f = tmpdir.join('README.md') f.write_binary(b'problem\n=======\n') - assert detect_merge_conflict([str(f.realpath()), '--assume-in-merge']) == 1 + assert main([str(f.realpath()), '--assume-in-merge']) == 1 diff --git a/tests/check_symlinks_test.py b/tests/check_symlinks_test.py index 0414df55..ecbc7aec 100644 --- a/tests/check_symlinks_test.py +++ b/tests/check_symlinks_test.py @@ -2,7 +2,7 @@ import pytest -from pre_commit_hooks.check_symlinks import check_symlinks +from pre_commit_hooks.check_symlinks import main xfail_symlink = pytest.mark.xfail(os.name == 'nt', reason='No symlink support') @@ -12,12 +12,12 @@ @pytest.mark.parametrize( ('dest', 'expected'), (('exists', 0), ('does-not-exist', 1)), ) -def test_check_symlinks(tmpdir, dest, expected): # pragma: no cover (symlinks) +def test_main(tmpdir, dest, expected): # pragma: no cover (symlinks) tmpdir.join('exists').ensure() symlink = tmpdir.join('symlink') symlink.mksymlinkto(tmpdir.join(dest)) - assert check_symlinks((symlink.strpath,)) == expected + assert main((symlink.strpath,)) == expected -def test_check_symlinks_normal_file(tmpdir): - assert check_symlinks((tmpdir.join('f').ensure().strpath,)) == 0 +def test_main_normal_file(tmpdir): + assert main((tmpdir.join('f').ensure().strpath,)) == 0 diff --git a/tests/check_xml_test.py b/tests/check_xml_test.py index 84e365d1..357bad64 100644 --- a/tests/check_xml_test.py +++ b/tests/check_xml_test.py @@ -1,6 +1,6 @@ import pytest -from pre_commit_hooks.check_xml import check_xml +from pre_commit_hooks.check_xml import main from testing.util import get_resource_path @@ -10,6 +10,6 @@ ('ok_xml.xml', 0), ), ) -def test_check_xml(filename, expected_retval): - ret = check_xml([get_resource_path(filename)]) +def test_main(filename, expected_retval): + ret = main([get_resource_path(filename)]) assert ret == expected_retval diff --git a/tests/check_yaml_test.py b/tests/check_yaml_test.py index aa357f13..d267150a 100644 --- a/tests/check_yaml_test.py +++ b/tests/check_yaml_test.py @@ -3,7 +3,7 @@ import pytest -from pre_commit_hooks.check_yaml import check_yaml +from pre_commit_hooks.check_yaml import main from testing.util import get_resource_path @@ -13,29 +13,29 @@ ('ok_yaml.yaml', 0), ), ) -def test_check_yaml(filename, expected_retval): - ret = check_yaml([get_resource_path(filename)]) +def test_main(filename, expected_retval): + ret = main([get_resource_path(filename)]) assert ret == expected_retval -def test_check_yaml_allow_multiple_documents(tmpdir): +def test_main_allow_multiple_documents(tmpdir): f = tmpdir.join('test.yaml') f.write('---\nfoo\n---\nbar\n') # should fail without the setting - assert check_yaml((f.strpath,)) + assert main((f.strpath,)) # should pass when we allow multiple documents - assert not check_yaml(('--allow-multiple-documents', f.strpath)) + assert not main(('--allow-multiple-documents', f.strpath)) def test_fails_even_with_allow_multiple_documents(tmpdir): f = tmpdir.join('test.yaml') f.write('[') - assert check_yaml(('--allow-multiple-documents', f.strpath)) + assert main(('--allow-multiple-documents', f.strpath)) -def test_check_yaml_unsafe(tmpdir): +def test_main_unsafe(tmpdir): f = tmpdir.join('test.yaml') f.write( 'some_foo: !vault |\n' @@ -43,12 +43,12 @@ def test_check_yaml_unsafe(tmpdir): ' deadbeefdeadbeefdeadbeef\n', ) # should fail "safe" check - assert check_yaml((f.strpath,)) + assert main((f.strpath,)) # should pass when we allow unsafe documents - assert not check_yaml(('--unsafe', f.strpath)) + assert not main(('--unsafe', f.strpath)) -def test_check_yaml_unsafe_still_fails_on_syntax_errors(tmpdir): +def test_main_unsafe_still_fails_on_syntax_errors(tmpdir): f = tmpdir.join('test.yaml') f.write('[') - assert check_yaml(('--unsafe', f.strpath)) + assert main(('--unsafe', f.strpath)) diff --git a/tests/detect_private_key_test.py b/tests/detect_private_key_test.py index fdd63a21..9266f2b0 100644 --- a/tests/detect_private_key_test.py +++ b/tests/detect_private_key_test.py @@ -1,6 +1,6 @@ import pytest -from pre_commit_hooks.detect_private_key import detect_private_key +from pre_commit_hooks.detect_private_key import main # Input, expected return value TESTS = ( @@ -18,7 +18,7 @@ @pytest.mark.parametrize(('input_s', 'expected_retval'), TESTS) -def test_detect_private_key(input_s, expected_retval, tmpdir): +def test_main(input_s, expected_retval, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - assert detect_private_key([path.strpath]) == expected_retval + assert main([path.strpath]) == expected_retval diff --git a/tests/end_of_file_fixer_test.py b/tests/end_of_file_fixer_test.py index f8710afc..7f644e76 100644 --- a/tests/end_of_file_fixer_test.py +++ b/tests/end_of_file_fixer_test.py @@ -2,8 +2,8 @@ import pytest -from pre_commit_hooks.end_of_file_fixer import end_of_file_fixer from pre_commit_hooks.end_of_file_fixer import fix_file +from pre_commit_hooks.end_of_file_fixer import main # Input, expected return value, expected output @@ -35,7 +35,7 @@ def test_integration(input_s, expected_retval, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - ret = end_of_file_fixer([path.strpath]) + ret = main([path.strpath]) file_output = path.read_binary() assert file_output == output diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py index c275bf71..e978ba27 100644 --- a/tests/no_commit_to_branch_test.py +++ b/tests/no_commit_to_branch_test.py @@ -11,24 +11,24 @@ def test_other_branch(temp_git_dir): with temp_git_dir.as_cwd(): cmd_output('git', 'checkout', '-b', 'anotherbranch') - assert is_on_branch(('master',)) is False + assert is_on_branch({'master'}) is False def test_multi_branch(temp_git_dir): with temp_git_dir.as_cwd(): cmd_output('git', 'checkout', '-b', 'another/branch') - assert is_on_branch(('master',)) is False + assert is_on_branch({'master'}) is False def test_multi_branch_fail(temp_git_dir): with temp_git_dir.as_cwd(): cmd_output('git', 'checkout', '-b', 'another/branch') - assert is_on_branch(('another/branch',)) is True + assert is_on_branch({'another/branch'}) is True def test_master_branch(temp_git_dir): with temp_git_dir.as_cwd(): - assert is_on_branch(('master',)) is True + assert is_on_branch({'master'}) is True def test_main_branch_call(temp_git_dir): diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 7ce7e160..8d82d746 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -3,8 +3,8 @@ import pytest from six import PY2 +from pre_commit_hooks.pretty_format_json import main from pre_commit_hooks.pretty_format_json import parse_num_to_int -from pre_commit_hooks.pretty_format_json import pretty_format_json from testing.util import get_resource_path @@ -23,8 +23,8 @@ def test_parse_num_to_int(): ('pretty_formatted_json.json', 0), ), ) -def test_pretty_format_json(filename, expected_retval): - ret = pretty_format_json([get_resource_path(filename)]) +def test_main(filename, expected_retval): + ret = main([get_resource_path(filename)]) assert ret == expected_retval @@ -36,8 +36,8 @@ def test_pretty_format_json(filename, expected_retval): ('pretty_formatted_json.json', 0), ), ) -def test_unsorted_pretty_format_json(filename, expected_retval): - ret = pretty_format_json(['--no-sort-keys', get_resource_path(filename)]) +def test_unsorted_main(filename, expected_retval): + ret = main(['--no-sort-keys', get_resource_path(filename)]) assert ret == expected_retval @@ -51,17 +51,17 @@ def test_unsorted_pretty_format_json(filename, expected_retval): ('tab_pretty_formatted_json.json', 0), ), ) -def test_tab_pretty_format_json(filename, expected_retval): # pragma: no cover - ret = pretty_format_json(['--indent', '\t', get_resource_path(filename)]) +def test_tab_main(filename, expected_retval): # pragma: no cover + ret = main(['--indent', '\t', get_resource_path(filename)]) assert ret == expected_retval -def test_non_ascii_pretty_format_json(): - ret = pretty_format_json(['--no-ensure-ascii', get_resource_path('non_ascii_pretty_formatted_json.json')]) +def test_non_ascii_main(): + ret = main(['--no-ensure-ascii', get_resource_path('non_ascii_pretty_formatted_json.json')]) assert ret == 0 -def test_autofix_pretty_format_json(tmpdir): +def test_autofix_main(tmpdir): srcfile = tmpdir.join('to_be_json_formatted.json') shutil.copyfile( get_resource_path('not_pretty_formatted_json.json'), @@ -69,30 +69,30 @@ def test_autofix_pretty_format_json(tmpdir): ) # now launch the autofix on that file - ret = pretty_format_json(['--autofix', srcfile.strpath]) + ret = main(['--autofix', srcfile.strpath]) # it should have formatted it assert ret == 1 # file was formatted (shouldn't trigger linter again) - ret = pretty_format_json([srcfile.strpath]) + ret = main([srcfile.strpath]) assert ret == 0 def test_orderfile_get_pretty_format(): - ret = pretty_format_json(['--top-keys=alist', get_resource_path('pretty_formatted_json.json')]) + ret = main(['--top-keys=alist', get_resource_path('pretty_formatted_json.json')]) assert ret == 0 def test_not_orderfile_get_pretty_format(): - ret = pretty_format_json(['--top-keys=blah', get_resource_path('pretty_formatted_json.json')]) + ret = main(['--top-keys=blah', get_resource_path('pretty_formatted_json.json')]) assert ret == 1 def test_top_sorted_get_pretty_format(): - ret = pretty_format_json(['--top-keys=01-alist,alist', get_resource_path('top_sorted_json.json')]) + ret = main(['--top-keys=01-alist,alist', get_resource_path('top_sorted_json.json')]) assert ret == 0 -def test_badfile_pretty_format_json(): - ret = pretty_format_json([get_resource_path('ok_yaml.yaml')]) +def test_badfile_main(): + ret = main([get_resource_path('ok_yaml.yaml')]) assert ret == 1 diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index 437cebd9..b3a79423 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -1,7 +1,7 @@ import pytest from pre_commit_hooks.requirements_txt_fixer import FAIL -from pre_commit_hooks.requirements_txt_fixer import fix_requirements_txt +from pre_commit_hooks.requirements_txt_fixer import main from pre_commit_hooks.requirements_txt_fixer import PASS from pre_commit_hooks.requirements_txt_fixer import Requirement @@ -36,7 +36,7 @@ def test_integration(input_s, expected_retval, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - output_retval = fix_requirements_txt([path.strpath]) + output_retval = main([path.strpath]) assert path.read_binary() == output assert output_retval == expected_retval @@ -44,7 +44,7 @@ def test_integration(input_s, expected_retval, output, tmpdir): def test_requirement_object(): top_of_file = Requirement() - top_of_file.comments.append('#foo') + top_of_file.comments.append(b'#foo') top_of_file.value = b'\n' requirement_foo = Requirement() diff --git a/tests/sort_simple_yaml_test.py b/tests/sort_simple_yaml_test.py index 176d12f5..72f5becc 100644 --- a/tests/sort_simple_yaml_test.py +++ b/tests/sort_simple_yaml_test.py @@ -110,9 +110,9 @@ def test_first_key(): lines = ['# some comment', '"a": 42', 'b: 17', '', 'c: 19'] assert first_key(lines) == 'a": 42' - # no lines + # no lines (not a real situation) lines = [] - assert first_key(lines) is None + assert first_key(lines) == '' @pytest.mark.parametrize('bad_lines,good_lines,_', TEST_SORTS) diff --git a/tests/tests_should_end_in_test_test.py b/tests/tests_should_end_in_test_test.py index dc686a5f..4eb98e7d 100644 --- a/tests/tests_should_end_in_test_test.py +++ b/tests/tests_should_end_in_test_test.py @@ -1,36 +1,36 @@ -from pre_commit_hooks.tests_should_end_in_test import validate_files +from pre_commit_hooks.tests_should_end_in_test import main -def test_validate_files_all_pass(): - ret = validate_files(['foo_test.py', 'bar_test.py']) +def test_main_all_pass(): + ret = main(['foo_test.py', 'bar_test.py']) assert ret == 0 -def test_validate_files_one_fails(): - ret = validate_files(['not_test_ending.py', 'foo_test.py']) +def test_main_one_fails(): + ret = main(['not_test_ending.py', 'foo_test.py']) assert ret == 1 -def test_validate_files_django_all_pass(): - ret = validate_files(['--django', 'tests.py', 'test_foo.py', 'test_bar.py', 'tests/test_baz.py']) +def test_main_django_all_pass(): + ret = main(['--django', 'tests.py', 'test_foo.py', 'test_bar.py', 'tests/test_baz.py']) assert ret == 0 -def test_validate_files_django_one_fails(): - ret = validate_files(['--django', 'not_test_ending.py', 'test_foo.py']) +def test_main_django_one_fails(): + ret = main(['--django', 'not_test_ending.py', 'test_foo.py']) assert ret == 1 def test_validate_nested_files_django_one_fails(): - ret = validate_files(['--django', 'tests/not_test_ending.py', 'test_foo.py']) + ret = main(['--django', 'tests/not_test_ending.py', 'test_foo.py']) assert ret == 1 -def test_validate_files_not_django_fails(): - ret = validate_files(['foo_test.py', 'bar_test.py', 'test_baz.py']) +def test_main_not_django_fails(): + ret = main(['foo_test.py', 'bar_test.py', 'test_baz.py']) assert ret == 1 -def test_validate_files_django_fails(): - ret = validate_files(['--django', 'foo_test.py', 'test_bar.py', 'test_baz.py']) +def test_main_django_fails(): + ret = main(['--django', 'foo_test.py', 'test_bar.py', 'test_baz.py']) assert ret == 1 diff --git a/tox.ini b/tox.ini index c131e6f0..d1e6a796 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] # These should match the travis env list -envlist = py27,py36,py37,pypy +envlist = py27,py36,py37,pypy3 [testenv] deps = -rrequirements-dev.txt From 93e3a4f3eea9da721f1d16855ab2ddc0e1518e32 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei <6d0847b9@opayq.com> Date: Sat, 2 Feb 2019 10:38:39 +0200 Subject: [PATCH 008/334] Don't run check-executables-have-shebangs and trailing-whitespace-fixer hooks for the commit-msg stage --- .pre-commit-hooks.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index bd1b6736..79a90b71 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -45,6 +45,7 @@ entry: check-executables-have-shebangs language: python types: [text, executable] + stages: [commit, push, manual] - id: check-json name: Check JSON description: This hook checks json files for parseable syntax. @@ -184,3 +185,4 @@ entry: trailing-whitespace-fixer language: python types: [text] + stages: [commit, push, manual] From 4575652bd2d34a931c89a0689c052ccd53da9d50 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 11 Feb 2019 19:56:15 -0800 Subject: [PATCH 009/334] Use default flake8 config --- pre_commit_hooks/check_builtin_literals.py | 31 ++++++++++-------- .../check_executables_have_shebangs.py | 3 +- pre_commit_hooks/check_json.py | 2 +- pre_commit_hooks/check_yaml.py | 2 +- pre_commit_hooks/detect_aws_credentials.py | 20 ++++++------ pre_commit_hooks/fix_encoding_pragma.py | 4 ++- pre_commit_hooks/pretty_format_json.py | 13 +++++--- pre_commit_hooks/requirements_txt_fixer.py | 5 ++- pre_commit_hooks/trailing_whitespace_fixer.py | 4 +-- setup.py | 26 +++++++-------- tests/check_builtin_literals_test.py | 32 ++++++++++--------- tests/detect_aws_credentials_test.py | 15 ++++----- tests/pretty_format_json_test.py | 17 +++++++--- tests/requirements_txt_fixer_test.py | 18 +++++++++-- tests/tests_should_end_in_test_test.py | 5 ++- tox.ini | 3 -- 16 files changed, 119 insertions(+), 81 deletions(-) diff --git a/pre_commit_hooks/check_builtin_literals.py b/pre_commit_hooks/check_builtin_literals.py index 874c68c5..4ddaa8c6 100644 --- a/pre_commit_hooks/check_builtin_literals.py +++ b/pre_commit_hooks/check_builtin_literals.py @@ -21,22 +21,23 @@ } -BuiltinTypeCall = collections.namedtuple('BuiltinTypeCall', ['name', 'line', 'column']) +Call = collections.namedtuple('Call', ['name', 'line', 'column']) -class BuiltinTypeVisitor(ast.NodeVisitor): +class Visitor(ast.NodeVisitor): def __init__(self, ignore=None, allow_dict_kwargs=True): # type: (Optional[Sequence[str]], bool) -> None - self.builtin_type_calls = [] # type: List[BuiltinTypeCall] + self.builtin_type_calls = [] # type: List[Call] self.ignore = set(ignore) if ignore else set() self.allow_dict_kwargs = allow_dict_kwargs def _check_dict_call(self, node): # type: (ast.Call) -> bool - - return self.allow_dict_kwargs and (getattr(node, 'kwargs', None) or getattr(node, 'keywords', None)) + return ( + self.allow_dict_kwargs and + (getattr(node, 'kwargs', None) or getattr(node, 'keywords', None)) + ) def visit_Call(self, node): # type: (ast.Call) -> None - if not isinstance(node.func, ast.Name): # Ignore functions that are object attributes (`foo.bar()`). # Assume that if the user calls `builtins.list()`, they know what @@ -49,15 +50,15 @@ def visit_Call(self, node): # type: (ast.Call) -> None elif node.args: return self.builtin_type_calls.append( - BuiltinTypeCall(node.func.id, node.lineno, node.col_offset), + Call(node.func.id, node.lineno, node.col_offset), ) -def check_file_for_builtin_type_constructors(filename, ignore=None, allow_dict_kwargs=True): - # type: (str, Optional[Sequence[str]], bool) -> List[BuiltinTypeCall] +def check_file(filename, ignore=None, allow_dict_kwargs=True): + # type: (str, Optional[Sequence[str]], bool) -> List[Call] with open(filename, 'rb') as f: tree = ast.parse(f.read(), filename=filename) - visitor = BuiltinTypeVisitor(ignore=ignore, allow_dict_kwargs=allow_dict_kwargs) + visitor = Visitor(ignore=ignore, allow_dict_kwargs=allow_dict_kwargs) visitor.visit(tree) return visitor.builtin_type_calls @@ -73,14 +74,17 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int mutex = parser.add_mutually_exclusive_group(required=False) mutex.add_argument('--allow-dict-kwargs', action='store_true') - mutex.add_argument('--no-allow-dict-kwargs', dest='allow_dict_kwargs', action='store_false') + mutex.add_argument( + '--no-allow-dict-kwargs', + dest='allow_dict_kwargs', action='store_false', + ) mutex.set_defaults(allow_dict_kwargs=True) args = parser.parse_args(argv) rc = 0 for filename in args.filenames: - calls = check_file_for_builtin_type_constructors( + calls = check_file( filename, ignore=args.ignore, allow_dict_kwargs=args.allow_dict_kwargs, @@ -89,7 +93,8 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int rc = rc or 1 for call in calls: print( - '{filename}:{call.line}:{call.column} - Replace {call.name}() with {replacement}'.format( + '{filename}:{call.line}:{call.column}: ' + 'replace {call.name}() with {replacement}'.format( filename=filename, call=call, replacement=BUILTIN_TYPES[call.name], diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index c936a5dd..4db2f9fb 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -18,7 +18,8 @@ def check_has_shebang(path): # type: (str) -> int print( '{path}: marked executable but has no (or invalid) shebang!\n' " If it isn't supposed to be executable, try: chmod -x {quoted}\n" - ' If it is supposed to be executable, double-check its shebang.'.format( + ' If it is supposed to be executable, double-check its shebang.' + .format( path=path, quoted=pipes.quote(path), ), diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py index b9393508..f26e0a5b 100644 --- a/pre_commit_hooks/check_json.py +++ b/pre_commit_hooks/check_json.py @@ -10,7 +10,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() - parser.add_argument('filenames', nargs='*', help='JSON filenames to check.') + parser.add_argument('filenames', nargs='*', help='Filenames to check.') args = parser.parse_args(argv) retval = 0 diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index b638684b..c8665aa4 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -50,7 +50,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int 'Implies --allow-multiple-documents' ), ) - parser.add_argument('filenames', nargs='*', help='Yaml filenames to check.') + parser.add_argument('filenames', nargs='*', help='Filenames to check.') args = parser.parse_args(argv) load_fn = LOAD_FNS[Key(multi=args.multi, unsafe=args.unsafe)] diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index 3c87d117..da80ab4f 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -12,16 +12,16 @@ from six.moves import configparser -def get_aws_credential_files_from_env(): # type: () -> Set[str] +def get_aws_cred_files_from_env(): # type: () -> Set[str] """Extract credential file paths from environment variables.""" - files = set() - for env_var in ( - 'AWS_CONFIG_FILE', 'AWS_CREDENTIAL_FILE', 'AWS_SHARED_CREDENTIALS_FILE', - 'BOTO_CONFIG', - ): - if env_var in os.environ: - files.add(os.environ[env_var]) - return files + return { + os.environ[env_var] + for env_var in ( + 'AWS_CONFIG_FILE', 'AWS_CREDENTIAL_FILE', + 'AWS_SHARED_CREDENTIALS_FILE', 'BOTO_CONFIG', + ) + if env_var in os.environ + } def get_aws_secrets_from_env(): # type: () -> Set[str] @@ -115,7 +115,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int # Add the credentials files configured via environment variables to the set # of files to to gather AWS secrets from. - credential_files |= get_aws_credential_files_from_env() + credential_files |= get_aws_cred_files_from_env() keys = set() # type: Set[str] for credential_file in credential_files: diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index b0b5c8ec..dbe9c6cc 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -110,7 +110,9 @@ def _to_disp(pragma): # type: (bytes) -> str def main(argv=None): # type: (Optional[Sequence[str]]) -> int - parser = argparse.ArgumentParser('Fixes the encoding pragma of python files') + parser = argparse.ArgumentParser( + 'Fixes the encoding pragma of python files', + ) parser.add_argument('filenames', nargs='*', help='Filenames to fix') parser.add_argument( '--pragma', default=DEFAULT_PRAGMA, type=_normalize_pragma, diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index de7f8d71..e734ca81 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -15,8 +15,9 @@ from six import text_type -def _get_pretty_format(contents, indent, ensure_ascii=True, sort_keys=True, top_keys=()): - # type: (str, str, bool, bool, Sequence[str]) -> str +def _get_pretty_format( + contents, indent, ensure_ascii=True, sort_keys=True, top_keys=(), +): # type: (str, str, bool, bool, Sequence[str]) -> str def pairs_first(pairs): # type: (Sequence[Tuple[str, str]]) -> Mapping[str, str] before = [pair for pair in pairs if pair[0] in top_keys] @@ -29,7 +30,8 @@ def pairs_first(pairs): json.loads(contents, object_pairs_hook=pairs_first), indent=indent, ensure_ascii=ensure_ascii, - separators=(',', ': '), # Workaround for https://bugs.python.org/issue16333 + # Workaround for https://bugs.python.org/issue16333 + separators=(',', ': '), ) # Ensure unicode (Py2) and add the newline that dumps does not end with. return text_type(json_pretty) + '\n' @@ -75,7 +77,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int action='store_true', dest='no_ensure_ascii', default=False, - help='Do NOT convert non-ASCII characters to Unicode escape sequences (\\uXXXX)', + help=( + 'Do NOT convert non-ASCII characters to Unicode escape sequences ' + '(\\uXXXX)' + ), ) parser.add_argument( '--no-sort-keys', diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 3f85a17a..4575975a 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -61,7 +61,10 @@ def fix_requirements(f): # type: (IO[bytes]) -> int # If we see a newline before any requirements, then this is a # top of file comment. if len(requirements) == 1 and line.strip() == b'': - if len(requirement.comments) and requirement.comments[0].startswith(b'#'): + if ( + len(requirement.comments) and + requirement.comments[0].startswith(b'#') + ): requirement.value = b'\n' else: requirement.comments.append(line) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 4fe7975e..b2b64180 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -60,12 +60,12 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if '' in md_args: parser.error('--markdown-linebreak-ext requires a non-empty argument') all_markdown = '*' in md_args - # normalize all extensions; split at ',', lowercase, and force 1 leading '.' + # normalize extensions; split at ',', lowercase, and force 1 leading '.' md_exts = [ '.' + x.lower().lstrip('.') for x in ','.join(md_args).split(',') ] - # reject probable "eaten" filename as extension (skip leading '.' with [1:]) + # reject probable "eaten" filename as extension: skip leading '.' with [1:] for ext in md_exts: if any(c in ext[1:] for c in r'./\:'): parser.error( diff --git a/setup.py b/setup.py index 756500b2..d61244f5 100644 --- a/setup.py +++ b/setup.py @@ -32,34 +32,34 @@ entry_points={ 'console_scripts': [ 'autopep8-wrapper = pre_commit_hooks.autopep8_wrapper:main', - 'check-added-large-files = pre_commit_hooks.check_added_large_files:main', + 'check-added-large-files = pre_commit_hooks.check_added_large_files:main', # noqa: E501 'check-ast = pre_commit_hooks.check_ast:main', - 'check-builtin-literals = pre_commit_hooks.check_builtin_literals:main', - 'check-byte-order-marker = pre_commit_hooks.check_byte_order_marker:main', + 'check-builtin-literals = pre_commit_hooks.check_builtin_literals:main', # noqa: E501 + 'check-byte-order-marker = pre_commit_hooks.check_byte_order_marker:main', # noqa: E501 'check-case-conflict = pre_commit_hooks.check_case_conflict:main', - 'check-docstring-first = pre_commit_hooks.check_docstring_first:main', - 'check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main', + 'check-docstring-first = pre_commit_hooks.check_docstring_first:main', # noqa: E501 + 'check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main', # noqa: E501 'check-json = pre_commit_hooks.check_json:main', - 'check-merge-conflict = pre_commit_hooks.check_merge_conflict:main', + 'check-merge-conflict = pre_commit_hooks.check_merge_conflict:main', # noqa: E501 'check-symlinks = pre_commit_hooks.check_symlinks:main', - 'check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main', + 'check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main', # noqa: E501 'check-xml = pre_commit_hooks.check_xml:main', 'check-yaml = pre_commit_hooks.check_yaml:main', - 'debug-statement-hook = pre_commit_hooks.debug_statement_hook:main', - 'detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main', + 'debug-statement-hook = pre_commit_hooks.debug_statement_hook:main', # noqa: E501 + 'detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main', # noqa: E501 'detect-private-key = pre_commit_hooks.detect_private_key:main', 'double-quote-string-fixer = pre_commit_hooks.string_fixer:main', 'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:main', - 'file-contents-sorter = pre_commit_hooks.file_contents_sorter:main', + 'file-contents-sorter = pre_commit_hooks.file_contents_sorter:main', # noqa: E501 'fix-encoding-pragma = pre_commit_hooks.fix_encoding_pragma:main', - 'forbid-new-submodules = pre_commit_hooks.forbid_new_submodules:main', + 'forbid-new-submodules = pre_commit_hooks.forbid_new_submodules:main', # noqa: E501 'mixed-line-ending = pre_commit_hooks.mixed_line_ending:main', 'name-tests-test = pre_commit_hooks.tests_should_end_in_test:main', 'no-commit-to-branch = pre_commit_hooks.no_commit_to_branch:main', 'pretty-format-json = pre_commit_hooks.pretty_format_json:main', - 'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main', + 'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main', # noqa: E501 'sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main', - 'trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main', + 'trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main', # noqa: E501 ], }, ) diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py index d4ac30f8..dbb9cc42 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -2,9 +2,9 @@ import pytest -from pre_commit_hooks.check_builtin_literals import BuiltinTypeCall -from pre_commit_hooks.check_builtin_literals import BuiltinTypeVisitor +from pre_commit_hooks.check_builtin_literals import Call from pre_commit_hooks.check_builtin_literals import main +from pre_commit_hooks.check_builtin_literals import Visitor BUILTIN_CONSTRUCTORS = '''\ from six.moves import builtins @@ -38,7 +38,7 @@ @pytest.fixture def visitor(): - return BuiltinTypeVisitor() + return Visitor() @pytest.mark.parametrize( @@ -48,35 +48,35 @@ def visitor(): ('x[0]()', []), # complex ("0j", []), - ("complex()", [BuiltinTypeCall('complex', 1, 0)]), + ("complex()", [Call('complex', 1, 0)]), ("complex(0, 0)", []), ("complex('0+0j')", []), ('builtins.complex()', []), # float ("0.0", []), - ("float()", [BuiltinTypeCall('float', 1, 0)]), + ("float()", [Call('float', 1, 0)]), ("float('0.0')", []), ('builtins.float()', []), # int ("0", []), - ("int()", [BuiltinTypeCall('int', 1, 0)]), + ("int()", [Call('int', 1, 0)]), ("int('0')", []), ('builtins.int()', []), # list ("[]", []), - ("list()", [BuiltinTypeCall('list', 1, 0)]), + ("list()", [Call('list', 1, 0)]), ("list('abc')", []), ("list([c for c in 'abc'])", []), ("list(c for c in 'abc')", []), ('builtins.list()', []), # str ("''", []), - ("str()", [BuiltinTypeCall('str', 1, 0)]), + ("str()", [Call('str', 1, 0)]), ("str('0')", []), ('builtins.str()', []), # tuple ("()", []), - ("tuple()", [BuiltinTypeCall('tuple', 1, 0)]), + ("tuple()", [Call('tuple', 1, 0)]), ("tuple('abc')", []), ("tuple([c for c in 'abc'])", []), ("tuple(c for c in 'abc')", []), @@ -92,7 +92,7 @@ def test_non_dict_exprs(visitor, expression, calls): ('expression', 'calls'), [ ("{}", []), - ("dict()", [BuiltinTypeCall('dict', 1, 0)]), + ("dict()", [Call('dict', 1, 0)]), ("dict(a=1, b=2, c=3)", []), ("dict(**{'a': 1, 'b': 2, 'c': 3})", []), ("dict([(k, v) for k, v in [('a', 1), ('b', 2), ('c', 3)]])", []), @@ -108,20 +108,22 @@ def test_dict_allow_kwargs_exprs(visitor, expression, calls): @pytest.mark.parametrize( ('expression', 'calls'), [ - ("dict()", [BuiltinTypeCall('dict', 1, 0)]), - ("dict(a=1, b=2, c=3)", [BuiltinTypeCall('dict', 1, 0)]), - ("dict(**{'a': 1, 'b': 2, 'c': 3})", [BuiltinTypeCall('dict', 1, 0)]), + ("dict()", [Call('dict', 1, 0)]), + ("dict(a=1, b=2, c=3)", [Call('dict', 1, 0)]), + ("dict(**{'a': 1, 'b': 2, 'c': 3})", [Call('dict', 1, 0)]), ('builtins.dict()', []), ], ) def test_dict_no_allow_kwargs_exprs(expression, calls): - visitor = BuiltinTypeVisitor(allow_dict_kwargs=False) + visitor = Visitor(allow_dict_kwargs=False) visitor.visit(ast.parse(expression)) assert visitor.builtin_type_calls == calls def test_ignore_constructors(): - visitor = BuiltinTypeVisitor(ignore=('complex', 'dict', 'float', 'int', 'list', 'str', 'tuple')) + visitor = Visitor(ignore=( + 'complex', 'dict', 'float', 'int', 'list', 'str', 'tuple', + )) visitor.visit(ast.parse(BUILTIN_CONSTRUCTORS)) assert visitor.builtin_type_calls == [] diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py index f1bd7d43..31ba33e9 100644 --- a/tests/detect_aws_credentials_test.py +++ b/tests/detect_aws_credentials_test.py @@ -1,7 +1,7 @@ import pytest from mock import patch -from pre_commit_hooks.detect_aws_credentials import get_aws_credential_files_from_env +from pre_commit_hooks.detect_aws_credentials import get_aws_cred_files_from_env from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_file from pre_commit_hooks.detect_aws_credentials import main @@ -35,9 +35,8 @@ ), ) def test_get_aws_credentials_file_from_env(env_vars, values): - """Test that reading credential files names from environment variables works.""" with patch.dict('os.environ', env_vars, clear=True): - assert get_aws_credential_files_from_env() == values + assert get_aws_cred_files_from_env() == values @pytest.mark.parametrize( @@ -107,12 +106,11 @@ def test_get_aws_secrets_from_file(filename, expected_keys): ), ) def test_detect_aws_credentials(filename, expected_retval): - """Test if getting configured AWS secrets from files to be checked in works.""" - # with a valid credentials file ret = main(( get_resource_path(filename), - "--credentials-file=testing/resources/aws_config_with_multiple_sections.ini", + '--credentials-file', + 'testing/resources/aws_config_with_multiple_sections.ini', )) assert ret == expected_retval @@ -138,8 +136,9 @@ def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys): @patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file') @patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env') -def test_non_existent_credentials_with_allow_flag(mock_secrets_env, mock_secrets_file): - """Test behavior with no configured AWS secrets and flag to allow when missing.""" +def test_non_existent_credentials_with_allow_flag( + mock_secrets_env, mock_secrets_file, +): mock_secrets_env.return_value = set() mock_secrets_file.return_value = set() ret = main(( diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 8d82d746..bf7a16fa 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -57,7 +57,10 @@ def test_tab_main(filename, expected_retval): # pragma: no cover def test_non_ascii_main(): - ret = main(['--no-ensure-ascii', get_resource_path('non_ascii_pretty_formatted_json.json')]) + ret = main(( + '--no-ensure-ascii', + get_resource_path('non_ascii_pretty_formatted_json.json'), + )) assert ret == 0 @@ -79,17 +82,23 @@ def test_autofix_main(tmpdir): def test_orderfile_get_pretty_format(): - ret = main(['--top-keys=alist', get_resource_path('pretty_formatted_json.json')]) + ret = main(( + '--top-keys=alist', get_resource_path('pretty_formatted_json.json'), + )) assert ret == 0 def test_not_orderfile_get_pretty_format(): - ret = main(['--top-keys=blah', get_resource_path('pretty_formatted_json.json')]) + ret = main(( + '--top-keys=blah', get_resource_path('pretty_formatted_json.json'), + )) assert ret == 1 def test_top_sorted_get_pretty_format(): - ret = main(['--top-keys=01-alist,alist', get_resource_path('top_sorted_json.json')]) + ret = main(( + '--top-keys=01-alist,alist', get_resource_path('top_sorted_json.json'), + )) assert ret == 0 diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index b3a79423..c7c6e47a 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -15,13 +15,25 @@ (b'foo\n# comment at end\n', PASS, b'foo\n# comment at end\n'), (b'foo\nbar\n', FAIL, b'bar\nfoo\n'), (b'bar\nfoo\n', PASS, b'bar\nfoo\n'), - (b'#comment1\nfoo\n#comment2\nbar\n', FAIL, b'#comment2\nbar\n#comment1\nfoo\n'), - (b'#comment1\nbar\n#comment2\nfoo\n', PASS, b'#comment1\nbar\n#comment2\nfoo\n'), + ( + b'#comment1\nfoo\n#comment2\nbar\n', + FAIL, + b'#comment2\nbar\n#comment1\nfoo\n', + ), + ( + b'#comment1\nbar\n#comment2\nfoo\n', + PASS, + b'#comment1\nbar\n#comment2\nfoo\n', + ), (b'#comment\n\nfoo\nbar\n', FAIL, b'#comment\n\nbar\nfoo\n'), (b'#comment\n\nbar\nfoo\n', PASS, b'#comment\n\nbar\nfoo\n'), (b'\nfoo\nbar\n', FAIL, b'bar\n\nfoo\n'), (b'\nbar\nfoo\n', PASS, b'\nbar\nfoo\n'), - (b'pyramid==1\npyramid-foo==2\n', PASS, b'pyramid==1\npyramid-foo==2\n'), + ( + b'pyramid==1\npyramid-foo==2\n', + PASS, + b'pyramid==1\npyramid-foo==2\n', + ), (b'ocflib\nDjango\nPyMySQL\n', FAIL, b'Django\nocflib\nPyMySQL\n'), ( b'-e git+ssh://git_url@tag#egg=ocflib\nDjango\nPyMySQL\n', diff --git a/tests/tests_should_end_in_test_test.py b/tests/tests_should_end_in_test_test.py index 4eb98e7d..2acfa177 100644 --- a/tests/tests_should_end_in_test_test.py +++ b/tests/tests_should_end_in_test_test.py @@ -12,7 +12,10 @@ def test_main_one_fails(): def test_main_django_all_pass(): - ret = main(['--django', 'tests.py', 'test_foo.py', 'test_bar.py', 'tests/test_baz.py']) + ret = main(( + '--django', 'tests.py', 'test_foo.py', 'test_bar.py', + 'tests/test_baz.py', + )) assert ret == 0 diff --git a/tox.ini b/tox.ini index d1e6a796..3020bc01 100644 --- a/tox.ini +++ b/tox.ini @@ -17,8 +17,5 @@ commands = pre-commit install -f --install-hooks pre-commit run --all-files -[flake8] -max-line-length=131 - [pep8] ignore=E265,E501,W504 From 8626e266ddbf85ecdbd7f64d2950affd4f9ddd8b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 11 Feb 2019 19:57:37 -0800 Subject: [PATCH 010/334] double-quote-string-fixer --- .pre-commit-config.yaml | 1 + pre_commit_hooks/fix_encoding_pragma.py | 2 +- pre_commit_hooks/sort_simple_yaml.py | 4 +-- pre_commit_hooks/trailing_whitespace_fixer.py | 2 +- tests/check_builtin_literals_test.py | 34 +++++++++---------- tests/detect_aws_credentials_test.py | 6 ++-- tests/pretty_format_json_test.py | 2 +- tests/sort_simple_yaml_test.py | 2 +- 8 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 49905378..55c6f731 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,6 +10,7 @@ repos: - id: check-yaml - id: debug-statements - id: name-tests-test + - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://gitlab.com/pycqa/flake8 rev: 3.7.1 diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index dbe9c6cc..bde4e78a 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -147,5 +147,5 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int return retv -if __name__ == "__main__": +if __name__ == '__main__': exit(main()) diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py index 3c8ef165..a381679f 100755 --- a/pre_commit_hooks/sort_simple_yaml.py +++ b/pre_commit_hooks/sort_simple_yaml.py @@ -115,9 +115,9 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int new_lines = sort(lines) if lines != new_lines: - print("Fixing file `{filename}`".format(filename=filename)) + print('Fixing file `{filename}`'.format(filename=filename)) f.seek(0) - f.write("\n".join(new_lines) + "\n") + f.write('\n'.join(new_lines) + '\n') f.truncate() retval = 1 diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index b2b64180..2ccc0038 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -69,7 +69,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for ext in md_exts: if any(c in ext[1:] for c in r'./\:'): parser.error( - "bad --markdown-linebreak-ext extension {!r} (has . / \\ :)\n" + 'bad --markdown-linebreak-ext extension {!r} (has . / \\ :)\n' " (probably filename; use '--markdown-linebreak-ext=EXT')" .format(ext), ) diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py index dbb9cc42..19263b79 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -47,36 +47,36 @@ def visitor(): # see #285 ('x[0]()', []), # complex - ("0j", []), - ("complex()", [Call('complex', 1, 0)]), - ("complex(0, 0)", []), + ('0j', []), + ('complex()', [Call('complex', 1, 0)]), + ('complex(0, 0)', []), ("complex('0+0j')", []), ('builtins.complex()', []), # float - ("0.0", []), - ("float()", [Call('float', 1, 0)]), + ('0.0', []), + ('float()', [Call('float', 1, 0)]), ("float('0.0')", []), ('builtins.float()', []), # int - ("0", []), - ("int()", [Call('int', 1, 0)]), + ('0', []), + ('int()', [Call('int', 1, 0)]), ("int('0')", []), ('builtins.int()', []), # list - ("[]", []), - ("list()", [Call('list', 1, 0)]), + ('[]', []), + ('list()', [Call('list', 1, 0)]), ("list('abc')", []), ("list([c for c in 'abc'])", []), ("list(c for c in 'abc')", []), ('builtins.list()', []), # str ("''", []), - ("str()", [Call('str', 1, 0)]), + ('str()', [Call('str', 1, 0)]), ("str('0')", []), ('builtins.str()', []), # tuple - ("()", []), - ("tuple()", [Call('tuple', 1, 0)]), + ('()', []), + ('tuple()', [Call('tuple', 1, 0)]), ("tuple('abc')", []), ("tuple([c for c in 'abc'])", []), ("tuple(c for c in 'abc')", []), @@ -91,9 +91,9 @@ def test_non_dict_exprs(visitor, expression, calls): @pytest.mark.parametrize( ('expression', 'calls'), [ - ("{}", []), - ("dict()", [Call('dict', 1, 0)]), - ("dict(a=1, b=2, c=3)", []), + ('{}', []), + ('dict()', [Call('dict', 1, 0)]), + ('dict(a=1, b=2, c=3)', []), ("dict(**{'a': 1, 'b': 2, 'c': 3})", []), ("dict([(k, v) for k, v in [('a', 1), ('b', 2), ('c', 3)]])", []), ("dict((k, v) for k, v in [('a', 1), ('b', 2), ('c', 3)])", []), @@ -108,8 +108,8 @@ def test_dict_allow_kwargs_exprs(visitor, expression, calls): @pytest.mark.parametrize( ('expression', 'calls'), [ - ("dict()", [Call('dict', 1, 0)]), - ("dict(a=1, b=2, c=3)", [Call('dict', 1, 0)]), + ('dict()', [Call('dict', 1, 0)]), + ('dict(a=1, b=2, c=3)', [Call('dict', 1, 0)]), ("dict(**{'a': 1, 'b': 2, 'c': 3})", [Call('dict', 1, 0)]), ('builtins.dict()', []), ], diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py index 31ba33e9..777fb480 100644 --- a/tests/detect_aws_credentials_test.py +++ b/tests/detect_aws_credentials_test.py @@ -123,7 +123,7 @@ def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys): mock_secrets_file.return_value = set() ret = main(( get_resource_path('aws_config_without_secrets.ini'), - "--credentials-file=testing/resources/credentailsfilethatdoesntexist", + '--credentials-file=testing/resources/credentailsfilethatdoesntexist', )) assert ret == 2 out, _ = capsys.readouterr() @@ -143,7 +143,7 @@ def test_non_existent_credentials_with_allow_flag( mock_secrets_file.return_value = set() ret = main(( get_resource_path('aws_config_without_secrets.ini'), - "--credentials-file=testing/resources/credentailsfilethatdoesntexist", - "--allow-missing-credentials", + '--credentials-file=testing/resources/credentailsfilethatdoesntexist', + '--allow-missing-credentials', )) assert ret == 0 diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index bf7a16fa..3b7b9a24 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -41,7 +41,7 @@ def test_unsorted_main(filename, expected_retval): assert ret == expected_retval -@pytest.mark.skipif(PY2, reason="Requires Python3") +@pytest.mark.skipif(PY2, reason='Requires Python3') @pytest.mark.parametrize( ('filename', 'expected_retval'), ( ('not_pretty_formatted_json.json', 1), diff --git a/tests/sort_simple_yaml_test.py b/tests/sort_simple_yaml_test.py index 72f5becc..4261d5d4 100644 --- a/tests/sort_simple_yaml_test.py +++ b/tests/sort_simple_yaml_test.py @@ -45,7 +45,7 @@ def test_integration_good_bad_lines(tmpdir, bad_lines, good_lines, retval): file_path = os.path.join(tmpdir.strpath, 'foo.yaml') with open(file_path, 'w') as f: - f.write("\n".join(bad_lines) + "\n") + f.write('\n'.join(bad_lines) + '\n') assert main([file_path]) == retval From 1a5a5a232b67a8acb79ee4f3a9977441219ab4e9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 27 Feb 2019 22:12:12 -0800 Subject: [PATCH 011/334] Migrate setup.py to setup.cfg declarative metadata Committed via https://github.com/asottile/all-repos --- setup.cfg | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 65 +-------------------------------------------------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/setup.cfg b/setup.cfg index 2be68365..3dea0664 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,71 @@ +[metadata] +name = pre_commit_hooks +version = 2.1.0 +description = Some out-of-the-box hooks for pre-commit. +long_description = file: README.md +long_description_content_type = text/markdown +url = https://github.com/pre-commit/pre-commit-hooks +author = Anthony Sottile +author_email = asottile@umich.edu +license = MIT +license_file = LICENSE +classifiers = + License :: OSI Approved :: MIT License + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: Implementation :: CPython + Programming Language :: Python :: Implementation :: PyPy + +[options] +packages = find: +install_requires = + flake8 + ruamel.yaml>=0.15 + six + typing; python_version<"3.5" +python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +[options.entry_points] +console_scripts = + autopep8-wrapper = pre_commit_hooks.autopep8_wrapper:main + check-added-large-files = pre_commit_hooks.check_added_large_files:main + check-ast = pre_commit_hooks.check_ast:main + check-builtin-literals = pre_commit_hooks.check_builtin_literals:main + check-byte-order-marker = pre_commit_hooks.check_byte_order_marker:main + check-case-conflict = pre_commit_hooks.check_case_conflict:main + check-docstring-first = pre_commit_hooks.check_docstring_first:main + check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main + check-json = pre_commit_hooks.check_json:main + check-merge-conflict = pre_commit_hooks.check_merge_conflict:main + check-symlinks = pre_commit_hooks.check_symlinks:main + check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main + check-xml = pre_commit_hooks.check_xml:main + check-yaml = pre_commit_hooks.check_yaml:main + debug-statement-hook = pre_commit_hooks.debug_statement_hook:main + detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main + detect-private-key = pre_commit_hooks.detect_private_key:main + double-quote-string-fixer = pre_commit_hooks.string_fixer:main + end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:main + file-contents-sorter = pre_commit_hooks.file_contents_sorter:main + fix-encoding-pragma = pre_commit_hooks.fix_encoding_pragma:main + forbid-new-submodules = pre_commit_hooks.forbid_new_submodules:main + mixed-line-ending = pre_commit_hooks.mixed_line_ending:main + name-tests-test = pre_commit_hooks.tests_should_end_in_test:main + no-commit-to-branch = pre_commit_hooks.no_commit_to_branch:main + pretty-format-json = pre_commit_hooks.pretty_format_json:main + requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main + sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main + trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main + +[options.packages.find] +exclude = + tests* + testing* + [bdist_wheel] universal = True diff --git a/setup.py b/setup.py index d61244f5..8bf1ba93 100644 --- a/setup.py +++ b/setup.py @@ -1,65 +1,2 @@ -from setuptools import find_packages from setuptools import setup - - -setup( - name='pre_commit_hooks', - description='Some out-of-the-box hooks for pre-commit.', - url='https://github.com/pre-commit/pre-commit-hooks', - version='2.1.0', - - author='Anthony Sottile', - author_email='asottile@umich.edu', - - classifiers=[ - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy', - ], - - packages=find_packages(exclude=('tests*', 'testing*')), - install_requires=[ - 'flake8', - 'ruamel.yaml>=0.15', - 'six', - ], - extras_require={':python_version<"3.5"': ['typing']}, - entry_points={ - 'console_scripts': [ - 'autopep8-wrapper = pre_commit_hooks.autopep8_wrapper:main', - 'check-added-large-files = pre_commit_hooks.check_added_large_files:main', # noqa: E501 - 'check-ast = pre_commit_hooks.check_ast:main', - 'check-builtin-literals = pre_commit_hooks.check_builtin_literals:main', # noqa: E501 - 'check-byte-order-marker = pre_commit_hooks.check_byte_order_marker:main', # noqa: E501 - 'check-case-conflict = pre_commit_hooks.check_case_conflict:main', - 'check-docstring-first = pre_commit_hooks.check_docstring_first:main', # noqa: E501 - 'check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main', # noqa: E501 - 'check-json = pre_commit_hooks.check_json:main', - 'check-merge-conflict = pre_commit_hooks.check_merge_conflict:main', # noqa: E501 - 'check-symlinks = pre_commit_hooks.check_symlinks:main', - 'check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main', # noqa: E501 - 'check-xml = pre_commit_hooks.check_xml:main', - 'check-yaml = pre_commit_hooks.check_yaml:main', - 'debug-statement-hook = pre_commit_hooks.debug_statement_hook:main', # noqa: E501 - 'detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main', # noqa: E501 - 'detect-private-key = pre_commit_hooks.detect_private_key:main', - 'double-quote-string-fixer = pre_commit_hooks.string_fixer:main', - 'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:main', - 'file-contents-sorter = pre_commit_hooks.file_contents_sorter:main', # noqa: E501 - 'fix-encoding-pragma = pre_commit_hooks.fix_encoding_pragma:main', - 'forbid-new-submodules = pre_commit_hooks.forbid_new_submodules:main', # noqa: E501 - 'mixed-line-ending = pre_commit_hooks.mixed_line_ending:main', - 'name-tests-test = pre_commit_hooks.tests_should_end_in_test:main', - 'no-commit-to-branch = pre_commit_hooks.no_commit_to_branch:main', - 'pretty-format-json = pre_commit_hooks.pretty_format_json:main', - 'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main', # noqa: E501 - 'sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main', - 'trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main', # noqa: E501 - ], - }, -) +setup() From 01850a34c7bbd8bf600768d0511f30b8f732993b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 10 Mar 2019 15:24:38 -0700 Subject: [PATCH 012/334] Use ruamel.yaml for readme_test --- tests/readme_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/readme_test.py b/tests/readme_test.py index b2d03b35..fd6d2654 100644 --- a/tests/readme_test.py +++ b/tests/readme_test.py @@ -3,7 +3,7 @@ import io -import yaml +from pre_commit_hooks.check_yaml import yaml def test_readme_contains_all_hooks(): From 8bb94f0bd4211dc1eb5da7b13865f122256b52ac Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 10 Mar 2019 13:42:05 -0700 Subject: [PATCH 013/334] azure pipelines [skip travis] [skip appveyor] --- .coveragerc | 1 - .travis.yml | 22 -------------- README.md | 7 ++--- appveyor.yml | 17 ----------- azure-pipelines.yml | 25 ++++++++++++++++ get-git-lfs.py | 42 --------------------------- pre_commit_hooks/util.py | 2 -- tests/check_added_large_files_test.py | 5 ++-- tests/check_merge_conflict_test.py | 6 ++-- tox.ini | 1 - 10 files changed, 33 insertions(+), 95 deletions(-) delete mode 100644 .travis.yml delete mode 100644 appveyor.yml create mode 100644 azure-pipelines.yml delete mode 100755 get-git-lfs.py diff --git a/.coveragerc b/.coveragerc index 0a55c5f6..7c592a95 100644 --- a/.coveragerc +++ b/.coveragerc @@ -6,7 +6,6 @@ omit = .tox/* /usr/* setup.py - get-git-lfs.py [report] show_missing = True diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fa16ccef..00000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -dist: xenial -language: python -matrix: - include: # These should match the tox env list - - env: TOXENV=py27 - - env: TOXENV=py36 - python: 3.6 - - env: TOXENV=py37 - python: 3.7 - - env: TOXENV=pypy - python: pypy2.7-5.10.0 -install: pip install coveralls tox -script: tox -before_install: - # Install git-lfs for a test - - './get-git-lfs.py && export PATH="/tmp/git-lfs:$PATH"' -after_success: coveralls -cache: - directories: - - $HOME/.cache/pip - - $HOME/.cache/pre-commit - - /tmp/git-lfs diff --git a/README.md b/README.md index 177c4be7..a937771a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -[![Build Status](https://travis-ci.org/pre-commit/pre-commit-hooks.svg?branch=master)](https://travis-ci.org/pre-commit/pre-commit-hooks) -[![Coverage Status](https://coveralls.io/repos/github/pre-commit/pre-commit-hooks/badge.svg?branch=master)](https://coveralls.io/github/pre-commit/pre-commit-hooks?branch=master) -[![Build status](https://ci.appveyor.com/api/projects/status/dfcpng35u4g0r0t1/branch/master?svg=true)](https://ci.appveyor.com/project/asottile/pre-commit-hooks/branch/master) +[![Build Status](https://asottile.visualstudio.com/asottile/_apis/build/status/pre-commit.pre-commit-hooks?branchName=master)](https://asottile.visualstudio.com/asottile/_build/latest?definitionId=17&branchName=master) +[![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/asottile/asottile/17/master.svg)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=17&branchName=master) pre-commit-hooks -========== +================ Some out-of-the-box hooks for pre-commit. diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 395320b2..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,17 +0,0 @@ -environment: - matrix: - - TOXENV: py27 - - TOXENV: py37 - -install: - - "SET PATH=C:\\Python37;C:\\Python37\\Scripts;%PATH%" - - pip install tox - -# Not a C# project -build: false - -test_script: tox - -cache: - - '%LOCALAPPDATA%\pip\cache' - - '%USERPROFILE%\.cache\pre-commit' diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000..ab4c896a --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,25 @@ +trigger: + branches: + include: [master, test-me-*] + +resources: + repositories: + - repository: asottile + type: github + endpoint: asottile-github + name: asottile/azure-pipeline-templates + ref: refs/tags/v0.0.8 + +jobs: +- template: job--python-tox.yml@asottile + parameters: + toxenvs: [py27, py37] + os: windows + pre_test: + - script: git lfs +- template: job--python-tox.yml@asottile + parameters: + toxenvs: [pypy, py27, py36, py37] + os: linux + pre_test: + - script: git lfs diff --git a/get-git-lfs.py b/get-git-lfs.py deleted file mode 100755 index 4b09cac6..00000000 --- a/get-git-lfs.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 -"""This is a script to install git-lfs to a tempdir for use in tests""" -import io -import os.path -import shutil -import tarfile -import urllib.request -from typing import cast -from typing import IO - -DOWNLOAD_PATH = ( - 'https://github.com/github/git-lfs/releases/download/' - 'v2.2.1/git-lfs-linux-amd64-2.2.1.tar.gz' -) -PATH_IN_TAR = 'git-lfs-2.2.1/git-lfs' -DEST_PATH = '/tmp/git-lfs/git-lfs' -DEST_DIR = os.path.dirname(DEST_PATH) - - -def main(): # type: () -> int - if ( - os.path.exists(DEST_PATH) and - os.path.isfile(DEST_PATH) and - os.access(DEST_PATH, os.X_OK) - ): - print('Already installed!') - return 0 - - shutil.rmtree(DEST_DIR, ignore_errors=True) - os.makedirs(DEST_DIR, exist_ok=True) - - contents = io.BytesIO(urllib.request.urlopen(DOWNLOAD_PATH).read()) - with tarfile.open(fileobj=contents) as tar: - with cast(IO[bytes], tar.extractfile(PATH_IN_TAR)) as src_file: - with open(DEST_PATH, 'wb') as dest_file: - shutil.copyfileobj(src_file, dest_file) - os.chmod(DEST_PATH, 0o755) - return 0 - - -if __name__ == '__main__': - exit(main()) diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py index 5d1d11bd..d68e7699 100644 --- a/pre_commit_hooks/util.py +++ b/pre_commit_hooks/util.py @@ -24,8 +24,6 @@ def cmd_output(*cmd, **kwargs): # type: (*str, **Any) -> str proc = subprocess.Popen(cmd, **kwargs) stdout, stderr = proc.communicate() stdout = stdout.decode('UTF-8') - if stderr is not None: - stderr = stderr.decode('UTF-8') if retcode is not None and proc.returncode != retcode: raise CalledProcessError(cmd, retcode, proc.returncode, stdout, stderr) return stdout diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index 06671d7e..7f5e4183 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -1,7 +1,7 @@ from __future__ import absolute_import from __future__ import unicode_literals -import subprocess +import distutils.spawn import pytest @@ -67,8 +67,7 @@ def test_integration(temp_git_dir): def has_gitlfs(): - output = cmd_output('git', 'lfs', retcode=None, stderr=subprocess.STDOUT) - return 'git lfs status' in output + return distutils.spawn.find_executable('git-lfs') is not None xfailif_no_gitlfs = pytest.mark.xfail( diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index 50e389c9..af7cc43b 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -22,7 +22,7 @@ def f1_is_a_conflict_file(tmpdir): cmd_output('git', 'init', '--', repo1.strpath) with repo1.as_cwd(): repo1_f1.ensure() - cmd_output('git', 'add', '--', repo1_f1.strpath) + cmd_output('git', 'add', '.') cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'commit1') cmd_output('git', 'clone', repo1.strpath, repo2.strpath) @@ -77,7 +77,7 @@ def repository_pending_merge(tmpdir): cmd_output('git', 'init', repo1.strpath) with repo1.as_cwd(): repo1_f1.ensure() - cmd_output('git', 'add', '--', repo1_f1.strpath) + cmd_output('git', 'add', '.') cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'commit1') cmd_output('git', 'clone', repo1.strpath, repo2.strpath) @@ -90,7 +90,7 @@ def repository_pending_merge(tmpdir): # Commit in clone and pull without committing with repo2.as_cwd(): repo2_f2.write('child\n') - cmd_output('git', 'add', '--', repo2_f2.strpath) + cmd_output('git', 'add', '.') cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'clone commit2') cmd_output('git', 'pull', '--no-commit', '--no-rebase') # We should end up in a pending merge diff --git a/tox.ini b/tox.ini index 3020bc01..590783a5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,4 @@ [tox] -# These should match the travis env list envlist = py27,py36,py37,pypy3 [testenv] From d85c06d9a6f4057c4daba14de781637810a1a3f0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 10 Mar 2019 17:29:03 -0700 Subject: [PATCH 014/334] Use more generic github endpoint name --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ab4c896a..7b331b94 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,7 +6,7 @@ resources: repositories: - repository: asottile type: github - endpoint: asottile-github + endpoint: github name: asottile/azure-pipeline-templates ref: refs/tags/v0.0.8 From 3337b5ec0dd780e2b2bb4019d0afccd43e7785de Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 17 Mar 2019 11:00:24 -0700 Subject: [PATCH 015/334] Trigger azure pipelines on tags Committed via https://github.com/asottile/all-repos --- azure-pipelines.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7b331b94..974a7051 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,6 +1,8 @@ trigger: branches: include: [master, test-me-*] + tags: + include: ['*'] resources: repositories: From 841c47ebf7b56de951f67784fb7704c725e3ea40 Mon Sep 17 00:00:00 2001 From: Toby Fleming Date: Thu, 21 Mar 2019 16:33:00 -0700 Subject: [PATCH 016/334] Run check-byte-order-marker against all text types, not just Python files --- .pre-commit-hooks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 79a90b71..9396d55d 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -21,7 +21,7 @@ description: Forbid files which have a UTF-8 byte-order marker entry: check-byte-order-marker language: python - types: [python] + types: [text] - id: check-builtin-literals name: Check builtin type constructor use description: Require literal syntax when initializing empty or zero Python builtin types. From 2f6a2515ec3e93cbbb89232fc2056c812fc75cab Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 30 Mar 2019 15:31:42 -0700 Subject: [PATCH 017/334] Don't require an encoding for check-docstring-first --- pre_commit_hooks/check_docstring_first.py | 21 ++++++++++----- tests/check_docstring_first_test.py | 32 ++++++++++++++--------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/pre_commit_hooks/check_docstring_first.py b/pre_commit_hooks/check_docstring_first.py index f4639f17..6c19381c 100644 --- a/pre_commit_hooks/check_docstring_first.py +++ b/pre_commit_hooks/check_docstring_first.py @@ -8,14 +8,23 @@ from typing import Optional from typing import Sequence +import six -NON_CODE_TOKENS = frozenset(( - tokenize.COMMENT, tokenize.ENDMARKER, tokenize.NEWLINE, tokenize.NL, -)) +if six.PY2: # pragma: no cover (PY2) + from tokenize import generate_tokens as tokenize_tokenize + OTHER_NON_CODE = () +else: # pragma: no cover (PY3) + from tokenize import tokenize as tokenize_tokenize + OTHER_NON_CODE = (tokenize.ENCODING,) + +NON_CODE_TOKENS = frozenset( + (tokenize.COMMENT, tokenize.ENDMARKER, tokenize.NEWLINE, tokenize.NL) + + OTHER_NON_CODE, +) def check_docstring_first(src, filename=''): - # type: (str, str) -> int + # type: (bytes, str) -> int """Returns nonzero if the source has what looks like a docstring that is not at the beginning of the source. @@ -25,7 +34,7 @@ def check_docstring_first(src, filename=''): found_docstring_line = None found_code_line = None - tok_gen = tokenize.generate_tokens(io.StringIO(src).readline) + tok_gen = tokenize_tokenize(io.BytesIO(src).readline) for tok_type, _, (sline, scol), _, _ in tok_gen: # Looks like a docstring! if tok_type == tokenize.STRING and scol == 0: @@ -61,7 +70,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int retv = 0 for filename in args.filenames: - with io.open(filename, encoding='UTF-8') as f: + with open(filename, 'rb') as f: contents = f.read() retv |= check_docstring_first(contents, filename=filename) diff --git a/tests/check_docstring_first_test.py b/tests/check_docstring_first_test.py index aa9898d3..0973a58f 100644 --- a/tests/check_docstring_first_test.py +++ b/tests/check_docstring_first_test.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import unicode_literals @@ -10,37 +11,37 @@ # Contents, expected, expected_output TESTS = ( # trivial - ('', 0, ''), + (b'', 0, ''), # Acceptable - ('"foo"', 0, ''), + (b'"foo"', 0, ''), # Docstring after code ( - 'from __future__ import unicode_literals\n' - '"foo"\n', + b'from __future__ import unicode_literals\n' + b'"foo"\n', 1, '{filename}:2 Module docstring appears after code ' '(code seen on line 1).\n', ), # Test double docstring ( - '"The real docstring"\n' - 'from __future__ import absolute_import\n' - '"fake docstring"\n', + b'"The real docstring"\n' + b'from __future__ import absolute_import\n' + b'"fake docstring"\n', 1, '{filename}:3 Multiple module docstrings ' '(first docstring on line 1).\n', ), # Test multiple lines of code above ( - 'import os\n' - 'import sys\n' - '"docstring"\n', + b'import os\n' + b'import sys\n' + b'"docstring"\n', 1, '{filename}:3 Module docstring appears after code ' '(code seen on line 1).\n', ), # String literals in expressions are ok. - ('x = "foo"\n', 0, ''), + (b'x = "foo"\n', 0, ''), ) @@ -58,6 +59,13 @@ def test_unit(capsys, contents, expected, expected_out): @all_tests def test_integration(tmpdir, capsys, contents, expected, expected_out): f = tmpdir.join('test.py') - f.write(contents) + f.write_binary(contents) assert main([f.strpath]) == expected assert capsys.readouterr()[0] == expected_out.format(filename=f.strpath) + + +def test_arbitrary_encoding(tmpdir): + f = tmpdir.join('f.py') + contents = '# -*- coding: cp1252\nx = "£"'.encode('cp1252') + f.write_binary(contents) + assert main([f.strpath]) == 0 From d6847c4827dd9d2847f210979cb49e7e97b4060b Mon Sep 17 00:00:00 2001 From: Marc Jay Date: Tue, 9 Apr 2019 23:53:39 +0100 Subject: [PATCH 018/334] Add wildcard matching to no-commit-to-branch hook so that commits can be blocked on, for example, all release branches with 'release/*' --- README.md | 2 +- pre_commit_hooks/no_commit_to_branch.py | 8 +++++--- tests/no_commit_to_branch_test.py | 13 +++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a937771a..abcd0301 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Add this to your `.pre-commit-config.yaml` - `name-tests-test` - Assert that files in tests/ end in `_test.py`. - Use `args: ['--django']` to match `test*.py` instead. - `no-commit-to-branch` - Protect specific branches from direct checkins. - - Use `args: [--branch, staging, --branch, master]` to set the branch. + - Use `args: [--branch, staging, --branch, master, --branch, release/*]` to set the branch. `master` is the default if no argument is set. - `-b` / `--branch` may be specified multiple times to protect multiple branches. diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index 6b68c915..8729891e 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -1,6 +1,7 @@ from __future__ import print_function import argparse +import fnmatch from typing import Optional from typing import Sequence from typing import Set @@ -11,11 +12,12 @@ def is_on_branch(protected): # type: (Set[str]) -> bool try: - branch = cmd_output('git', 'symbolic-ref', 'HEAD') + ref_name = cmd_output('git', 'symbolic-ref', 'HEAD') except CalledProcessError: return False - chunks = branch.strip().split('/') - return '/'.join(chunks[2:]) in protected + chunks = ref_name.strip().split('/') + branch_name = '/'.join(chunks[2:]) + return any(fnmatch.fnmatch(branch_name, s) for s in protected) def main(argv=None): # type: (Optional[Sequence[str]]) -> int diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py index e978ba27..a83d8de7 100644 --- a/tests/no_commit_to_branch_test.py +++ b/tests/no_commit_to_branch_test.py @@ -44,6 +44,19 @@ def test_forbid_multiple_branches(temp_git_dir, branch_name): assert main(('--branch', 'b1', '--branch', 'b2')) +def test_branch_wildcard_fail(temp_git_dir): + with temp_git_dir.as_cwd(): + cmd_output('git', 'checkout', '-b', 'another/branch') + assert is_on_branch({'another/*'}) is True + + +@pytest.mark.parametrize('branch_name', ('master', 'another/branch')) +def test_branch_wildcard_multiple_branches_fail(temp_git_dir, branch_name): + with temp_git_dir.as_cwd(): + cmd_output('git', 'checkout', '-b', branch_name) + assert main(('--branch', 'master', '--branch', 'another/*')) + + def test_main_default_call(temp_git_dir): with temp_git_dir.as_cwd(): cmd_output('git', 'checkout', '-b', 'anotherbranch') From 8d2785b9d66fc1489b9a30669f4ebd5ce1ac7ffc Mon Sep 17 00:00:00 2001 From: Marc Jay Date: Sat, 20 Apr 2019 13:46:49 +0100 Subject: [PATCH 019/334] Amend approach for no-commit-to-branch to use regex matching based on feedback. Adds --pattern optional argument which can be used alongside --branch to block commits to a branch which matches a supplied regex expression --- README.md | 4 +++- pre_commit_hooks/no_commit_to_branch.py | 19 +++++++++++++++---- tests/no_commit_to_branch_test.py | 8 ++++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index abcd0301..96325b92 100644 --- a/README.md +++ b/README.md @@ -79,10 +79,12 @@ Add this to your `.pre-commit-config.yaml` - `name-tests-test` - Assert that files in tests/ end in `_test.py`. - Use `args: ['--django']` to match `test*.py` instead. - `no-commit-to-branch` - Protect specific branches from direct checkins. - - Use `args: [--branch, staging, --branch, master, --branch, release/*]` to set the branch. + - Use `args: [--branch, staging, --branch, master]` to set the branch. `master` is the default if no argument is set. - `-b` / `--branch` may be specified multiple times to protect multiple branches. + - `-p` / `--pattern` can be used to protect branches that match a supplied regex + (e.g. `--pattern, release/.*`). May be specified multiple times. - `pretty-format-json` - Checks that all your JSON files are pretty. "Pretty" here means that keys are sorted and indented. You can configure this with the following commandline options: diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index 8729891e..585eadc5 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -1,7 +1,7 @@ from __future__ import print_function import argparse -import fnmatch +import re from typing import Optional from typing import Sequence from typing import Set @@ -10,14 +10,17 @@ from pre_commit_hooks.util import cmd_output -def is_on_branch(protected): # type: (Set[str]) -> bool +def is_on_branch(protected, patterns=set()): + # type: (Set[str], Set[str]) -> bool try: ref_name = cmd_output('git', 'symbolic-ref', 'HEAD') except CalledProcessError: return False chunks = ref_name.strip().split('/') branch_name = '/'.join(chunks[2:]) - return any(fnmatch.fnmatch(branch_name, s) for s in protected) + return branch_name in protected or any( + re.match(p, branch_name) for p in patterns + ) def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -26,10 +29,18 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int '-b', '--branch', action='append', help='branch to disallow commits to, may be specified multiple times', ) + parser.add_argument( + '-p', '--pattern', action='append', + help=( + 'regex pattern for branch name to disallow commits to, ' + 'May be specified multiple times' + ), + ) args = parser.parse_args(argv) protected = set(args.branch or ('master',)) - return int(is_on_branch(protected)) + patterns = set(args.pattern or ()) + return int(is_on_branch(protected, patterns)) if __name__ == '__main__': diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py index a83d8de7..a2ab1f1a 100644 --- a/tests/no_commit_to_branch_test.py +++ b/tests/no_commit_to_branch_test.py @@ -44,17 +44,17 @@ def test_forbid_multiple_branches(temp_git_dir, branch_name): assert main(('--branch', 'b1', '--branch', 'b2')) -def test_branch_wildcard_fail(temp_git_dir): +def test_branch_pattern_fail(temp_git_dir): with temp_git_dir.as_cwd(): cmd_output('git', 'checkout', '-b', 'another/branch') - assert is_on_branch({'another/*'}) is True + assert is_on_branch(set(), {'another/.*'}) is True @pytest.mark.parametrize('branch_name', ('master', 'another/branch')) -def test_branch_wildcard_multiple_branches_fail(temp_git_dir, branch_name): +def test_branch_pattern_multiple_branches_fail(temp_git_dir, branch_name): with temp_git_dir.as_cwd(): cmd_output('git', 'checkout', '-b', branch_name) - assert main(('--branch', 'master', '--branch', 'another/*')) + assert main(('--branch', 'master', '--pattern', 'another/.*')) def test_main_default_call(temp_git_dir): From 7b959d140fe77075e5688697f5cf5eb1eeed8c97 Mon Sep 17 00:00:00 2001 From: Marc Jay Date: Sat, 20 Apr 2019 13:52:59 +0100 Subject: [PATCH 020/334] Tidy up indentation in README changes for no-commit-to-branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 96325b92..df060a28 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ Add this to your `.pre-commit-config.yaml` - `-b` / `--branch` may be specified multiple times to protect multiple branches. - `-p` / `--pattern` can be used to protect branches that match a supplied regex - (e.g. `--pattern, release/.*`). May be specified multiple times. + (e.g. `--pattern, release/.*`). May be specified multiple times. - `pretty-format-json` - Checks that all your JSON files are pretty. "Pretty" here means that keys are sorted and indented. You can configure this with the following commandline options: From 6568414fc568257fd9fa705e886e3f5e3adcffc0 Mon Sep 17 00:00:00 2001 From: Marc Jay Date: Sat, 20 Apr 2019 14:06:59 +0100 Subject: [PATCH 021/334] Clarify default behaviour in README for no-commit-to-branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df060a28..5bf28d3f 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Add this to your `.pre-commit-config.yaml` - Use `args: ['--django']` to match `test*.py` instead. - `no-commit-to-branch` - Protect specific branches from direct checkins. - Use `args: [--branch, staging, --branch, master]` to set the branch. - `master` is the default if no argument is set. + `master` is the default if no branch argument is set. - `-b` / `--branch` may be specified multiple times to protect multiple branches. - `-p` / `--pattern` can be used to protect branches that match a supplied regex From a7af81244972ae6ac30bd55260af46b7ce25a6e1 Mon Sep 17 00:00:00 2001 From: Marc Jay Date: Sat, 20 Apr 2019 23:07:14 +0100 Subject: [PATCH 022/334] Make optional argument use an immutable set for the default value in no-commit-to-branch. Make other sets immutable to satisfy type-checking and be consistent --- pre_commit_hooks/no_commit_to_branch.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index 585eadc5..a1015f45 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -2,16 +2,16 @@ import argparse import re +from typing import FrozenSet from typing import Optional from typing import Sequence -from typing import Set from pre_commit_hooks.util import CalledProcessError from pre_commit_hooks.util import cmd_output -def is_on_branch(protected, patterns=set()): - # type: (Set[str], Set[str]) -> bool +def is_on_branch(protected, patterns=frozenset()): + # type: (FrozenSet[str], FrozenSet[str]) -> bool try: ref_name = cmd_output('git', 'symbolic-ref', 'HEAD') except CalledProcessError: @@ -33,13 +33,13 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int '-p', '--pattern', action='append', help=( 'regex pattern for branch name to disallow commits to, ' - 'May be specified multiple times' + 'may be specified multiple times' ), ) args = parser.parse_args(argv) - protected = set(args.branch or ('master',)) - patterns = set(args.pattern or ()) + protected = frozenset(args.branch or ('master',)) + patterns = frozenset(args.pattern or ()) return int(is_on_branch(protected, patterns)) From 053feb1e6f78595fed43f3b61899532ea9b45934 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 20 Apr 2019 16:21:58 -0700 Subject: [PATCH 023/334] Use AbstractSet to appease mypy --- pre_commit_hooks/no_commit_to_branch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index a1015f45..31310595 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -2,7 +2,7 @@ import argparse import re -from typing import FrozenSet +from typing import AbstractSet from typing import Optional from typing import Sequence @@ -11,7 +11,7 @@ def is_on_branch(protected, patterns=frozenset()): - # type: (FrozenSet[str], FrozenSet[str]) -> bool + # type: (AbstractSet[str], AbstractSet[str]) -> bool try: ref_name = cmd_output('git', 'symbolic-ref', 'HEAD') except CalledProcessError: From e7924b53e4e8807c6d639179ecfed028ae8d70cd Mon Sep 17 00:00:00 2001 From: roottool Date: Mon, 22 Apr 2019 03:48:18 +0900 Subject: [PATCH 024/334] Changed from open() to io.open() --- pre_commit_hooks/check_yaml.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index c8665aa4..9bbd36c5 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -3,6 +3,7 @@ import argparse import collections import sys +import io from typing import Any from typing import Generator from typing import Optional @@ -58,7 +59,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int retval = 0 for filename in args.filenames: try: - with open(filename) as f: + with io.open(filename, encoding='UTF-8') as f: load_fn(f) except ruamel.yaml.YAMLError as exc: print(exc) From 5b01ea52f2eb2853d557a9b589ffa40bde552393 Mon Sep 17 00:00:00 2001 From: roottool Date: Mon, 22 Apr 2019 04:11:18 +0900 Subject: [PATCH 025/334] empty commit From 47c89785e8a2a735c2ff23af8098e0a72f2dd69b Mon Sep 17 00:00:00 2001 From: roottool Date: Mon, 22 Apr 2019 04:17:09 +0900 Subject: [PATCH 026/334] Added newline --- pre_commit_hooks/check_yaml.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 9bbd36c5..9b0ac894 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -4,6 +4,7 @@ import collections import sys import io + from typing import Any from typing import Generator from typing import Optional From fc9fb8bfa84b0a187bd857a668de3ce1a41d9967 Mon Sep 17 00:00:00 2001 From: roottool Date: Mon, 22 Apr 2019 04:24:41 +0900 Subject: [PATCH 027/334] Changed position of 'import io' --- pre_commit_hooks/check_yaml.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 9b0ac894..5b664854 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -2,9 +2,8 @@ import argparse import collections -import sys import io - +import sys from typing import Any from typing import Generator from typing import Optional From 7905d805afaa2d0be85c7e5e476372bd463cb924 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 21 Apr 2019 13:12:53 -0700 Subject: [PATCH 028/334] v2.2.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 55c6f731..44a50204 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.1.0 + rev: v2.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 472a2915..2b074452 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +2.2.0 +===== + +### Features +- Switch from `pyyaml` to `ruamel.yaml` + - This enforces (among other things) duplicate key checking in yaml. + - #351 PR by @asottile. +- Add a new `--pattern` option to `no-commit-to-branch` for regex matching + branch names. + - #375 issue by @marcjay. + - #376 PR by @marcjay. + +### Fixes +- Set `require_serial: true` for flake8 + - flake8 internally uses multiprocessing. + - #358 PR by @asottile. +- Don't run `check-executables-have-shebangs` / `trailing-whitespace` hooks + during the `commit-msg` stage. + - #361 issue by @revolter. + - #362 PR by @revolter. +- Run `check-byte-order-marker` against `types: [text]` + - #371 PR by @tobywf. + - #372 PR by @tobywf. +- Do not require UTF-8-encoded files for `check-docstring-first` + - #345 issue by @x007007007. + - #374 PR by @asottile. + +### Misc. +- `pre-commit-hooks` now is type checked with mypy. + - #360 PR by @asottile. + 2.1.0 ===== diff --git a/README.md b/README.md index 5bf28d3f..590585b0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.1.0 # Use the ref you want to point at + rev: v2.2.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 3dea0664..1a1987f2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.1.0 +version = 2.2.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 9ee4347a8f71ec718b88cdd3cdac8eaf34de36d0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 21 Apr 2019 13:17:05 -0700 Subject: [PATCH 029/334] v2.2.1 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 44a50204..81e9e181 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.0 + rev: v2.2.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b074452..2fa5c960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +2.2.1 +===== + +### Fixes +- Use UTF-8 to load yaml files + - #377 issue by @roottool. + - #378 PR by @roottool. + 2.2.0 ===== diff --git a/README.md b/README.md index 590585b0..170337cd 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.0 # Use the ref you want to point at + rev: v2.2.1 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 1a1987f2..a28236ec 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.2.0 +version = 2.2.1 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From c898df99ed61b786c49cdc359032065314bbb7d0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 21 Apr 2019 16:12:19 -0700 Subject: [PATCH 030/334] Trim passenv (tox>=2.8) Committed via https://github.com/asottile/all-repos --- tox.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/tox.ini b/tox.ini index 590783a5..dd80ff68 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,6 @@ envlist = py27,py36,py37,pypy3 [testenv] deps = -rrequirements-dev.txt -passenv = HOME HOMEPATH PROGRAMDATA setenv = GIT_AUTHOR_NAME = "test" GIT_COMMITTER_NAME = "test" From 9eb0d699ec90268d2c1554a0ac2ed2f910c08b47 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 28 Apr 2019 16:21:10 -0700 Subject: [PATCH 031/334] speed up azure jobs Committed via https://github.com/asottile/all-repos --- azure-pipelines.yml | 7 ++----- tox.ini | 10 +++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 974a7051..3156958c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,15 +13,12 @@ resources: ref: refs/tags/v0.0.8 jobs: +- template: job--pre-commit.yml@asottile - template: job--python-tox.yml@asottile parameters: toxenvs: [py27, py37] os: windows - pre_test: - - script: git lfs - template: job--python-tox.yml@asottile parameters: - toxenvs: [pypy, py27, py36, py37] + toxenvs: [pypy, pypy3, py27, py36, py37] os: linux - pre_test: - - script: git lfs diff --git a/tox.ini b/tox.ini index dd80ff68..a6b3fb4d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py36,py37,pypy3 +envlist = py27,py36,py37,pypy,pypy3,pre-commit [testenv] deps = -rrequirements-dev.txt @@ -12,8 +12,12 @@ commands = coverage erase coverage run -m pytest {posargs:tests} coverage report --fail-under 100 - pre-commit install -f --install-hooks - pre-commit run --all-files + pre-commit install + +[testenv:pre-commit] +skip_install = true +deps = pre-commit +commands = pre-commit run --all-files --show-diff-on-failure [pep8] ignore=E265,E501,W504 From 8bb09ce4072ca2d020fc5d6a1c4625d3cb4db62f Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 8 May 2019 14:30:29 -0700 Subject: [PATCH 032/334] Combine mypy.ini and setup.cfg Committed via https://github.com/asottile/all-repos --- mypy.ini | 12 ------------ setup.cfg | 13 +++++++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) delete mode 100644 mypy.ini diff --git a/mypy.ini b/mypy.ini deleted file mode 100644 index ee62c89f..00000000 --- a/mypy.ini +++ /dev/null @@ -1,12 +0,0 @@ -[mypy] -check_untyped_defs = true -disallow_any_generics = true -disallow_incomplete_defs = true -disallow_untyped_defs = true -no_implicit_optional = true - -[mypy-testing.*] -disallow_untyped_defs = false - -[mypy-tests.*] -disallow_untyped_defs = false diff --git a/setup.cfg b/setup.cfg index a28236ec..2bc3d45c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -69,3 +69,16 @@ exclude = [bdist_wheel] universal = True + +[mypy] +check_untyped_defs = true +disallow_any_generics = true +disallow_incomplete_defs = true +disallow_untyped_defs = true +no_implicit_optional = true + +[mypy-testing.*] +disallow_untyped_defs = false + +[mypy-tests.*] +disallow_untyped_defs = false From 79a1b2676ef9a6c82944cb1fe3aa0c428fc69880 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 15 May 2019 10:04:18 -0700 Subject: [PATCH 033/334] Handle crlf endings in fix-encoding-pragma --- pre_commit_hooks/fix_encoding_pragma.py | 24 +++++++++++------------- tests/fix_encoding_pragma_test.py | 23 ++++++++++++++++++----- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index bde4e78a..23fc79fd 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -9,14 +9,14 @@ from typing import Sequence from typing import Union -DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-\n' +DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-' def has_coding(line): # type: (bytes) -> bool if not line.strip(): return False return ( - line.lstrip()[0:1] == b'#' and ( + line.lstrip()[:1] == b'#' and ( b'unicode' in line or b'encoding' in line or b'coding:' in line or @@ -26,7 +26,7 @@ def has_coding(line): # type: (bytes) -> bool class ExpectedContents(collections.namedtuple( - 'ExpectedContents', ('shebang', 'rest', 'pragma_status'), + 'ExpectedContents', ('shebang', 'rest', 'pragma_status', 'ending'), )): """ pragma_status: @@ -47,6 +47,8 @@ def is_expected_pragma(self, remove): # type: (bool) -> bool def _get_expected_contents(first_line, second_line, rest, expected_pragma): # type: (bytes, bytes, bytes, bytes) -> ExpectedContents + ending = b'\r\n' if first_line.endswith(b'\r\n') else b'\n' + if first_line.startswith(b'#!'): shebang = first_line potential_coding = second_line @@ -55,7 +57,7 @@ def _get_expected_contents(first_line, second_line, rest, expected_pragma): potential_coding = first_line rest = second_line + rest - if potential_coding == expected_pragma: + if potential_coding.rstrip(b'\r\n') == expected_pragma: pragma_status = True # type: Optional[bool] elif has_coding(potential_coding): pragma_status = None @@ -64,7 +66,7 @@ def _get_expected_contents(first_line, second_line, rest, expected_pragma): rest = potential_coding + rest return ExpectedContents( - shebang=shebang, rest=rest, pragma_status=pragma_status, + shebang=shebang, rest=rest, pragma_status=pragma_status, ending=ending, ) @@ -93,7 +95,7 @@ def fix_encoding_pragma(f, remove=False, expected_pragma=DEFAULT_PRAGMA): f.truncate() f.write(expected.shebang) if not remove: - f.write(expected_pragma) + f.write(expected_pragma + expected.ending) f.write(expected.rest) return 1 @@ -102,11 +104,7 @@ def fix_encoding_pragma(f, remove=False, expected_pragma=DEFAULT_PRAGMA): def _normalize_pragma(pragma): # type: (Union[bytes, str]) -> bytes if not isinstance(pragma, bytes): pragma = pragma.encode('UTF-8') - return pragma.rstrip() + b'\n' - - -def _to_disp(pragma): # type: (bytes) -> str - return pragma.decode().rstrip() + return pragma.rstrip() def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -117,7 +115,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser.add_argument( '--pragma', default=DEFAULT_PRAGMA, type=_normalize_pragma, help='The encoding pragma to use. Default: {}'.format( - _to_disp(DEFAULT_PRAGMA), + DEFAULT_PRAGMA.decode(), ), ) parser.add_argument( @@ -141,7 +139,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int retv |= file_ret if file_ret: print(fmt.format( - pragma=_to_disp(args.pragma), filename=filename, + pragma=args.pragma.decode(), filename=filename, )) return retv diff --git a/tests/fix_encoding_pragma_test.py b/tests/fix_encoding_pragma_test.py index 7288bfa1..d94b7256 100644 --- a/tests/fix_encoding_pragma_test.py +++ b/tests/fix_encoding_pragma_test.py @@ -112,7 +112,7 @@ def test_not_ok_inputs(input_str, output): def test_ok_input_alternate_pragma(): input_s = b'# coding: utf-8\nx = 1\n' bytesio = io.BytesIO(input_s) - ret = fix_encoding_pragma(bytesio, expected_pragma=b'# coding: utf-8\n') + ret = fix_encoding_pragma(bytesio, expected_pragma=b'# coding: utf-8') assert ret == 0 bytesio.seek(0) assert bytesio.read() == input_s @@ -120,7 +120,7 @@ def test_ok_input_alternate_pragma(): def test_not_ok_input_alternate_pragma(): bytesio = io.BytesIO(b'x = 1\n') - ret = fix_encoding_pragma(bytesio, expected_pragma=b'# coding: utf-8\n') + ret = fix_encoding_pragma(bytesio, expected_pragma=b'# coding: utf-8') assert ret == 1 bytesio.seek(0) assert bytesio.read() == b'# coding: utf-8\nx = 1\n' @@ -130,11 +130,11 @@ def test_not_ok_input_alternate_pragma(): ('input_s', 'expected'), ( # Python 2 cli parameters are bytes - (b'# coding: utf-8', b'# coding: utf-8\n'), + (b'# coding: utf-8', b'# coding: utf-8'), # Python 3 cli parameters are text - ('# coding: utf-8', b'# coding: utf-8\n'), + ('# coding: utf-8', b'# coding: utf-8'), # trailing whitespace - ('# coding: utf-8\n', b'# coding: utf-8\n'), + ('# coding: utf-8\n', b'# coding: utf-8'), ), ) def test_normalize_pragma(input_s, expected): @@ -150,3 +150,16 @@ def test_integration_alternate_pragma(tmpdir, capsys): assert f.read() == '# coding: utf-8\nx = 1\n' out, _ = capsys.readouterr() assert out == 'Added `# coding: utf-8` to {}\n'.format(f.strpath) + + +def test_crlf_ok(tmpdir): + f = tmpdir.join('f.py') + f.write_binary(b'# -*- coding: utf-8 -*-\r\nx = 1\r\n') + assert not main((f.strpath,)) + + +def test_crfl_adds(tmpdir): + f = tmpdir.join('f.py') + f.write_binary(b'x = 1\r\n') + assert main((f.strpath,)) + assert f.read_binary() == b'# -*- coding: utf-8 -*-\r\nx = 1\r\n' From e8e54f7f99d61a6f60373b87ac4932d70bda58d9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 15 May 2019 10:17:27 -0700 Subject: [PATCH 034/334] v2.2.2 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 81e9e181..20439031 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.1 + rev: v2.2.2 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fa5c960..3c9edf81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +2.2.2 +===== + +### Fixes +- Handle CRLF line endings in `fix-encoding-pragma` + - #384 PR by @asottile. + 2.2.1 ===== diff --git a/README.md b/README.md index 170337cd..a46b2378 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.1 # Use the ref you want to point at + rev: v2.2.2 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 2bc3d45c..ebb9df2e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.2.1 +version = 2.2.2 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 711b730b6738b04e0fc2adc23c5c4c059b633976 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 16 May 2019 09:42:04 -0700 Subject: [PATCH 035/334] Fix crlf line endings for double-quote-string-fixer --- pre_commit_hooks/string_fixer.py | 10 +++++----- tests/string_fixer_test.py | 9 ++++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py index a5ea1ea9..a41b7373 100644 --- a/pre_commit_hooks/string_fixer.py +++ b/pre_commit_hooks/string_fixer.py @@ -31,13 +31,13 @@ def handle_match(token_text): # type: (str) -> str def get_line_offsets_by_line_no(src): # type: (str) -> List[int] # Padded so we can index with line number offsets = [-1, 0] - for line in src.splitlines(): - offsets.append(offsets[-1] + len(line) + 1) + for line in src.splitlines(True): + offsets.append(offsets[-1] + len(line)) return offsets def fix_strings(filename): # type: (str) -> int - with io.open(filename, encoding='UTF-8') as f: + with io.open(filename, encoding='UTF-8', newline='') as f: contents = f.read() line_offsets = get_line_offsets_by_line_no(contents) @@ -58,8 +58,8 @@ def fix_strings(filename): # type: (str) -> int new_contents = ''.join(splitcontents) if contents != new_contents: - with io.open(filename, 'w', encoding='UTF-8') as write_handle: - write_handle.write(new_contents) + with io.open(filename, 'w', encoding='UTF-8', newline='') as f: + f.write(new_contents) return 1 else: return 0 diff --git a/tests/string_fixer_test.py b/tests/string_fixer_test.py index a65213b4..4adca4a5 100644 --- a/tests/string_fixer_test.py +++ b/tests/string_fixer_test.py @@ -44,8 +44,15 @@ @pytest.mark.parametrize(('input_s', 'output', 'expected_retval'), TESTS) def test_rewrite(input_s, output, expected_retval, tmpdir): - path = tmpdir.join('file.txt') + path = tmpdir.join('file.py') path.write(input_s) retval = main([path.strpath]) assert path.read() == output assert retval == expected_retval + + +def test_rewrite_crlf(tmpdir): + f = tmpdir.join('f.py') + f.write_binary(b'"foo"\r\n"bar"\r\n') + assert main((f.strpath,)) + assert f.read_binary() == b"'foo'\r\n'bar'\r\n" From 0b70e285e369bcb24b57b74929490ea7be9c4b19 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 16 May 2019 09:58:18 -0700 Subject: [PATCH 036/334] v2.2.3 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20439031..f77c36ef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.2 + rev: v2.2.3 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9edf81..7003dfb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +2.2.3 +===== + +### Fixes +- Handle CRLF line endings in `double-quote-string-fixer` + - #385 issue by @Trim21. + - #386 PR by @asottile. + 2.2.2 ===== diff --git a/README.md b/README.md index a46b2378..1a152de8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.2 # Use the ref you want to point at + rev: v2.2.3 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index ebb9df2e..96d5f5ae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.2.2 +version = 2.2.3 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From e34f0c44aa8d001930f4f416af4df6a94bcd4e90 Mon Sep 17 00:00:00 2001 From: Dan LaManna Date: Wed, 5 Jun 2019 12:29:23 -0400 Subject: [PATCH 037/334] Add the rpdb debugger to the list of debugger packages --- pre_commit_hooks/debug_statement_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 02dd3b29..48648734 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -10,7 +10,7 @@ from typing import Sequence -DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb'} +DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb', 'rpdb'} Debug = collections.namedtuple('Debug', ('line', 'col', 'name', 'reason')) From 37209942f84d7518a4885d392f01ed81a152fc9e Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Sat, 3 Aug 2019 12:14:05 +0100 Subject: [PATCH 038/334] Assure we have HOME defined during testing Fixed broken CI caused by missing HOME. Fixes: #402 --- tests/check_added_large_files_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index 7f5e4183..2f67d1b0 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -76,8 +76,9 @@ def has_gitlfs(): @xfailif_no_gitlfs -def test_allows_gitlfs(temp_git_dir): # pragma: no cover +def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover with temp_git_dir.as_cwd(): + monkeypatch.setenv(str('HOME'), str(temp_git_dir.strpath)) cmd_output('git', 'lfs', 'install') temp_git_dir.join('f.py').write('a' * 10000) cmd_output('git', 'lfs', 'track', 'f.py') @@ -87,8 +88,9 @@ def test_allows_gitlfs(temp_git_dir): # pragma: no cover @xfailif_no_gitlfs -def test_moves_with_gitlfs(temp_git_dir): # pragma: no cover +def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover with temp_git_dir.as_cwd(): + monkeypatch.setenv(str('HOME'), str(temp_git_dir.strpath)) cmd_output('git', 'lfs', 'install') cmd_output('git', 'lfs', 'track', 'a.bin', 'b.bin') # First add the file we're going to move From ae70f7e3c7619e024548b73bda56d08a7626983a Mon Sep 17 00:00:00 2001 From: Semyon Maryasin Date: Thu, 28 Mar 2019 01:13:45 +0300 Subject: [PATCH 039/334] Add check-toml hook --- .pre-commit-hooks.yaml | 6 ++++++ pre_commit_hooks/check_toml.py | 28 ++++++++++++++++++++++++++++ setup.cfg | 2 ++ 3 files changed, 36 insertions(+) create mode 100644 pre_commit_hooks/check_toml.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 9396d55d..7a3b380a 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -70,6 +70,12 @@ entry: check-symlinks language: python types: [symlink] +- id: check-toml + name: Check Toml + description: This hook checks toml files for parseable syntax. + entry: check-toml + language: python + types: [toml] - id: check-vcs-permalinks name: Check vcs permalinks description: Ensures that links to vcs websites are permalinks. diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py new file mode 100644 index 00000000..5f3b820c --- /dev/null +++ b/pre_commit_hooks/check_toml.py @@ -0,0 +1,28 @@ +from __future__ import print_function + +import argparse +import sys +from typing import Optional +from typing import Sequence + +import pytoml + + +def main(argv=None): # type: (Optional[Sequence[str]]) -> int + parser = argparse.ArgumentParser() + parser.add_argument('filenames', nargs='*', help='Filenames to check.') + args = parser.parse_args(argv) + + retval = 0 + for filename in args.filenames: + try: + with open(filename) as f: + pytoml.load(f) + except pytoml.TomlError as exc: + print(exc) + retval = 1 + return retval + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/setup.cfg b/setup.cfg index 96d5f5ae..742707b6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,6 +26,7 @@ packages = find: install_requires = flake8 ruamel.yaml>=0.15 + pytoml six typing; python_version<"3.5" python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* @@ -43,6 +44,7 @@ console_scripts = check-json = pre_commit_hooks.check_json:main check-merge-conflict = pre_commit_hooks.check_merge_conflict:main check-symlinks = pre_commit_hooks.check_symlinks:main + check-toml = pre_commit_hooks.check_toml:main check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main check-xml = pre_commit_hooks.check_xml:main check-yaml = pre_commit_hooks.check_yaml:main From 771156fb5e9cfc894f78e2369f217f5dd5f7b35a Mon Sep 17 00:00:00 2001 From: Semyon Maryasin Date: Thu, 28 Mar 2019 01:22:57 +0300 Subject: [PATCH 040/334] Use toml rather than pytoml Pytoml has an issue with error messages: https://github.com/avakar/pytoml/issues/41 --- pre_commit_hooks/check_toml.py | 6 +++--- setup.cfg | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py index 5f3b820c..370830cd 100644 --- a/pre_commit_hooks/check_toml.py +++ b/pre_commit_hooks/check_toml.py @@ -5,7 +5,7 @@ from typing import Optional from typing import Sequence -import pytoml +import toml def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -17,8 +17,8 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for filename in args.filenames: try: with open(filename) as f: - pytoml.load(f) - except pytoml.TomlError as exc: + toml.load(f) + except toml.TomlDecodeError as exc: print(exc) retval = 1 return retval diff --git a/setup.cfg b/setup.cfg index 742707b6..18d34928 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,7 @@ packages = find: install_requires = flake8 ruamel.yaml>=0.15 - pytoml + toml six typing; python_version<"3.5" python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* From 8d7d40c7cc93c1e5b2d12a36a4ea97926269e678 Mon Sep 17 00:00:00 2001 From: Semyon Maryasin Date: Thu, 28 Mar 2019 01:50:06 +0300 Subject: [PATCH 041/334] Add README entry for check-toml hook --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1a152de8..3614ea93 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Add this to your `.pre-commit-config.yaml` - `check-json` - Attempts to load all json files to verify syntax. - `check-merge-conflict` - Check for files that contain merge conflict strings. - `check-symlinks` - Checks for symlinks which do not point to anything. +- `check-toml` - Attempts to load all TOML files to verify syntax. - `check-vcs-permalinks` - Ensures that links to vcs websites are permalinks. - `check-xml` - Attempts to load all xml files to verify syntax. - `check-yaml` - Attempts to load all yaml files to verify syntax. From 611a4443d7b439e0896b119bd7c15fa93a05ec7e Mon Sep 17 00:00:00 2001 From: Squeaky Date: Sat, 3 Aug 2019 18:46:28 +0200 Subject: [PATCH 042/334] add sys.exit(main()) to file_contents_sorter.py --- pre_commit_hooks/file_contents_sorter.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 6f13c98a..1598d2da 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -12,6 +12,7 @@ from __future__ import print_function import argparse +import sys from typing import IO from typing import Optional from typing import Sequence @@ -53,3 +54,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int retv |= ret_for_file return retv + + +if __name__ == '__main__': + sys.exit(main()) From 317aef49610c5a9bb47838aa9a9863cb8090d829 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Sat, 3 Aug 2019 11:36:34 +0100 Subject: [PATCH 043/334] Added tests for check_toml Also assures we print filename when error occurs. --- pre_commit_hooks/check_toml.py | 2 +- tests/check_toml_test.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/check_toml_test.py diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py index 370830cd..e16e17c9 100644 --- a/pre_commit_hooks/check_toml.py +++ b/pre_commit_hooks/check_toml.py @@ -19,7 +19,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int with open(filename) as f: toml.load(f) except toml.TomlDecodeError as exc: - print(exc) + print('{}: {}'.format(filename, exc)) retval = 1 return retval diff --git a/tests/check_toml_test.py b/tests/check_toml_test.py new file mode 100644 index 00000000..1172c40a --- /dev/null +++ b/tests/check_toml_test.py @@ -0,0 +1,32 @@ +from __future__ import absolute_import +from __future__ import unicode_literals + +from pre_commit_hooks.check_toml import main + + +def test_toml_good(tmpdir): + filename = tmpdir.join('f') + filename.write(""" +key = # INVALID + += "no key name" # INVALID +""") + ret = main((filename.strpath,)) + assert ret == 1 + + +def test_toml_bad(tmpdir): + filename = tmpdir.join('f') + filename.write( + """ +# This is a TOML document. + +title = "TOML Example" + +[owner] +name = "John" +dob = 1979-05-27T07:32:00-08:00 # First class dates +""", + ) + ret = main((filename.strpath,)) + assert ret == 0 From d6d3bd94604578adbd918c5a00d531d98350d86f Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 5 Aug 2019 10:33:34 -0700 Subject: [PATCH 044/334] v2.3.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 19 +++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f77c36ef..d4a3a1aa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.3 + rev: v2.3.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 7003dfb9..4327dad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +2.3.0 +===== + +### Features +- Add `rpdb` to detected debuggers in `debug-statements` + - #389 PR by @danlamanna. +- Add `check-toml` hook + - #400 PR by @MarSoft. + - #400 PR by @ssbarnea. + +### Fixes +- Add `__main__` block to `pre_commit.file_contents_sorter` so it can be + invoked using `python -m` + - #405 PR by @squeaky-pl. + +### Misc. +- Fix `git-lfs` tests in azure pipelines + - #403 PR by @ssbarnea. + 2.2.3 ===== diff --git a/README.md b/README.md index 3614ea93..1950fa19 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.3 # Use the ref you want to point at + rev: v2.3.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 18d34928..4038836f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.2.3 +version = 2.3.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 3ed9b62aeca61d3e445f1219999b2ee1a72835b0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 11 Aug 2019 16:31:05 -0700 Subject: [PATCH 045/334] Add dates to changelog entries Automated with this script: ```bash git tag -l | sed 's/^v//g' | xargs --replace bash -c 'sed -r -i "s/^({})$/\1 - $(git show --format=%ad --date=short --no-patch v{})/g" CHANGELOG.md' sed -r -i 's/^(=+)$/\1=============/g' CHANGELOG.md # - 2019-01-01 ``` --- CHANGELOG.md | 152 +++++++++++++++++++++++++-------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4327dad3..8d2c3642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -2.3.0 -===== +2.3.0 - 2019-08-05 +================== ### Features - Add `rpdb` to detected debuggers in `debug-statements` @@ -17,31 +17,31 @@ - Fix `git-lfs` tests in azure pipelines - #403 PR by @ssbarnea. -2.2.3 -===== +2.2.3 - 2019-05-16 +================== ### Fixes - Handle CRLF line endings in `double-quote-string-fixer` - #385 issue by @Trim21. - #386 PR by @asottile. -2.2.2 -===== +2.2.2 - 2019-05-15 +================== ### Fixes - Handle CRLF line endings in `fix-encoding-pragma` - #384 PR by @asottile. -2.2.1 -===== +2.2.1 - 2019-04-21 +================== ### Fixes - Use UTF-8 to load yaml files - #377 issue by @roottool. - #378 PR by @roottool. -2.2.0 -===== +2.2.0 - 2019-04-20 +================== ### Features - Switch from `pyyaml` to `ruamel.yaml` @@ -71,8 +71,8 @@ - `pre-commit-hooks` now is type checked with mypy. - #360 PR by @asottile. -2.1.0 -===== +2.1.0 - 2018-12-26 +================== ### Features - Detect PGP/GPG private keys in `detect-private-key` @@ -93,8 +93,8 @@ - #343 PR by @TheKevJames. -2.0.0 -===== +2.0.0 - 2018-10-12 +================== ### Breaking changes @@ -125,8 +125,8 @@ [mirrors-autopep8]: https://github.com/pre-commit/mirrors-autopep8 -1.4.0-1 -======= +1.4.0-1 - 2018-09-27 +==================== (Note: this is a tag-only release as no code changes occurred) @@ -135,8 +135,8 @@ - #315 issue by @revolter. - #317 PR by @revolter. -1.4.0 -===== +1.4.0 - 2018-07-22 +================== ### Features - `no-commit-to-branch`: allow `--branch` to be specified multiple times @@ -159,8 +159,8 @@ - Test against python3.7 - #304 PR by @expobrain. -1.3.0 -===== +1.3.0 - 2018-05-28 +================== ### Features - Add an `--unsafe` argument to `check-yaml` to allow custom yaml tags @@ -181,23 +181,23 @@ - #285 issue by @EgoWumpus. - #286 PR by @asottile. -1.2.3 -===== +1.2.3 - 2018-02-28 +================== ### Fixes - `trailing-whitespace` entrypoint was incorrect. - f6780b9 by @asottile. -1.2.2 -===== +1.2.2 - 2018-02-28 +================== ### Fixes - `trailing-whitespace` no longer adds a missing newline at end-of-file - #270 issue by @fractos. - #271 PR by @asottile. -1.2.1-1 -======= +1.2.1-1 - 2018-02-24 +==================== (Note: this is a tag-only release as no code changes occurred) @@ -206,8 +206,8 @@ - #268 issue by @dongyuzheng. - #269 PR by @asottile. -1.2.1 -===== +1.2.1 - 2018-02-19 +================== ### Fixes: - `detect-aws-credentials` false positive when key was empty - #258 issue by @PVSec. @@ -216,8 +216,8 @@ - #265 issue by @hectorv. - #266 PR by @asottile. -1.2.0 -===== +1.2.0 - 2018-01-13 +================== ### Features: - Add new `check-builtin-literals` hook. - #249 #251 PR by @benwebber. @@ -227,14 +227,14 @@ - #255 issue by @SaMnCo @nicain. - #256 PR by @nicain. -1.1.1 -===== +1.1.1 - 2017-10-19 +================== ### Fixes: - Fix output interleaving in `check-vcs-permalinks` under python3. - #245 PR by @asottile. -1.1.0 -===== +1.1.0 - 2017-10-12 +================== ### Features: - `check-yaml` gains a `--allow-multiple-documents` (`-m`) argument to allow linting of files using the @@ -242,8 +242,8 @@ - pre-commit/pre-commit#635 issue by @geekobi. - #244 PR by @asottile. -1.0.0 -===== +1.0.0 - 2017-10-09 +================== ### Features: - New hook: `check-vcs-permalinks` for ensuring permalinked github urls. - #241 PR by @asottile. @@ -254,20 +254,20 @@ - Fix `requirements-txt-fixer` for files ending in comments - #243 PR by @asottile. -0.9.5 -===== +0.9.5 - 2017-09-27 +================== - Fix mixed-line-endings `--fix=...` when whole file is a different ending -0.9.4 -===== +0.9.4 - 2017-09-19 +================== - Fix entry point for `mixed-line-ending` -0.9.3 -===== +0.9.3 - 2017-09-07 +================== - New hook: `mixed-line-ending` -0.9.2 -===== +0.9.2 - 2017-08-21 +================== - Report full python version in `check-ast`. - Apply a more strict regular expression for `name-tests-test` - Upgrade binding for `git-lfs` for `check-added-large-files`. The oldest @@ -275,12 +275,12 @@ files as "lfs" (false negative) and earlier versions will crash. - `debug-statements` now works for non-utf-8 files. -0.9.1 -===== +0.9.1 - 2017-07-02 +================== - Add `check-executables-have-shebangs` hook. -0.9.0 -===== +0.9.0 - 2017-07-02 +================== - Add `sort-simple-yaml` hook - Fix `requirements-txt-fixer` for empty files - Add `file-contents-sorter` hook for sorting flat files @@ -289,24 +289,24 @@ allows the text processing hooks to match *all* text files (and to match files which would only be classifiable by their shebangs). -0.8.0 -===== +0.8.0 - 2017-06-06 +================== - Add flag allowing missing keys to `detect-aws-credentials` - Handle django default `tests.py` in `name-tests-test` - Add `--no-ensure-ascii` option to `pretty-format-json` - Add `no-commit-to-branch` hook -0.7.1 -===== +0.7.1 - 2017-02-07 +================== - Don't false positive on files where trailing whitespace isn't changed. -0.7.0 -===== +0.7.0 - 2017-01-21 +================== - Improve search for detecting aws keys - Add .pre-commit-hooks.yaml for forward compatibility -0.6.1 -===== +0.6.1 - 2016-11-30 +================== - trailing-whitespace-hook: restore original file on catastrophic failure - trailing-whitespace-hook: support crlf - check-yaml: Use safe_load @@ -314,20 +314,20 @@ - check-json: display filename for non-utf8 files - New hook: forbid-new-submodules -0.6.0 -===== +0.6.0 - 2016-08-12 +================== - Merge conflict detection no longer crashes on binary files - Indentation in json may be an arbitrary separator - Editable requirements are properly sorted - Encoding pragma fixer pragma is configurable -0.5.1 -===== +0.5.1 - 2016-05-16 +================== - Add a --no-sort-keys to json pretty formatter - Add a --remove to fix-encoding-pragma -0.5.0 -===== +0.5.0 - 2016-04-05 +================== - Add check-byte-order-marker - Add check-synlinks - check-large-files-added understands git-lfs @@ -340,8 +340,8 @@ - Allow binary files to pass private key hook - Add pretty-format-json hook -0.4.2 -===== +0.4.2 - 2015-05-31 +================== - Add --django to test name checker - Add check-merge-conflict hook - Remove dependency on plumbum @@ -350,13 +350,13 @@ - Teach trailing-whitespace about markdown - Quickfix for pyflakes - flake8 version conflict -0.4.1 -===== +0.4.1 - 2015-03-08 +================== - Respect configuration when running autopep8 - Quickfix for pep8 version conflicts -0.4.0 -===== +0.4.0 - 2015-02-22 +================== - Fix trailing-whitespace on OS X - Add check-added-large-files hook - Add check-docstring-first hook @@ -367,18 +367,18 @@ - Fix end-of-file-fixer for windows - Add double-quote-string-fixer hook -0.3.0 -===== +0.3.0 - 2014-08-22 +================== - Add autopep8-wrapper hook -0.2.0 -===== +0.2.0 - 2014-08-19 +================== - Add check-json hook -0.1.1 -===== +0.1.1 - 2014-06-19 +================== - Don't crash on non-parseable files for debug-statement-hook -0.1.0 -===== +0.1.0 - 2014-06-07 +================== - Initial Release From 3e9db01775648dc08689dd1bff3da2d54fc8ffda Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Thu, 15 Aug 2019 12:32:33 -0400 Subject: [PATCH 046/334] Add logic to print line number of JSON errors This commit makes the pretty JSON check more verbose when it encounters errors, that way developers can see which lines are causing errors in order to debug. --- pre_commit_hooks/pretty_format_json.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index e734ca81..f42630aa 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -115,6 +115,17 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if contents != pretty_contents: print('File {} is not pretty-formatted'.format(json_file)) + contents_by_line = ''.join(contents).split('\n') + pretty_contents_by_line = ''.join(pretty_contents).split('\n') + + diff = len(contents_by_line) - len(pretty_contents_by_line) + if diff > 0: + pretty_contents_by_line.extend([''] * diff) + + for line_num, line in enumerate(contents_by_line): + if line != pretty_contents_by_line[line_num]: + print('{}:{}'.format(json_file, line_num)) + if args.autofix: _autofix(json_file, pretty_contents) From 780f20249f8fdf4a1c3cb53eb8c5d02f40dace2a Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Fri, 16 Aug 2019 12:38:41 -0400 Subject: [PATCH 047/334] Add option to show expected output This prints a diff between the given json file and the expected (pretty) output, with this functionality hidden behind a cli flag --- pre_commit_hooks/pretty_format_json.py | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index f42630aa..475bf1c8 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -4,6 +4,7 @@ import io import json import sys +import difflib from collections import OrderedDict from typing import List from typing import Mapping @@ -55,6 +56,14 @@ def parse_topkeys(s): # type: (str) -> List[str] return s.split(',') +def get_diff(source, target): + source_lines = ''.join(source).split('\n') + target_lines = ''.join(target).split('\n') + d = difflib.Differ() + diff = d.compare(source_lines, target_lines) + return '\n'.join(diff) + + def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument( @@ -96,6 +105,13 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int default=[], help='Ordered list of keys to keep at the top of JSON hashes', ) + parser.add_argument( + '--show-expected', + action='store_true', + dest='show_expected', + default=False, + help='Show a diff between the input file and expected (pretty) output', + ) parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -115,16 +131,8 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if contents != pretty_contents: print('File {} is not pretty-formatted'.format(json_file)) - contents_by_line = ''.join(contents).split('\n') - pretty_contents_by_line = ''.join(pretty_contents).split('\n') - - diff = len(contents_by_line) - len(pretty_contents_by_line) - if diff > 0: - pretty_contents_by_line.extend([''] * diff) - - for line_num, line in enumerate(contents_by_line): - if line != pretty_contents_by_line[line_num]: - print('{}:{}'.format(json_file, line_num)) + if args.show_expected: + print(get_diff(contents, pretty_contents)) if args.autofix: _autofix(json_file, pretty_contents) From b28837a0389dca2fe401a13aabc7e668450ce968 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Fri, 23 Aug 2019 14:14:10 -0400 Subject: [PATCH 048/334] Add test case to test diffing function --- pre_commit_hooks/pretty_format_json.py | 6 +- tests/pretty_format_json_test.py | 76 ++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 475bf1c8..2e04064a 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -1,10 +1,10 @@ from __future__ import print_function import argparse +import difflib import io import json import sys -import difflib from collections import OrderedDict from typing import List from typing import Mapping @@ -56,7 +56,7 @@ def parse_topkeys(s): # type: (str) -> List[str] return s.split(',') -def get_diff(source, target): +def get_diff(source, target): # type: (List[str], List[str]) -> str source_lines = ''.join(source).split('\n') target_lines = ''.join(target).split('\n') d = difflib.Differ() @@ -132,7 +132,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int print('File {} is not pretty-formatted'.format(json_file)) if args.show_expected: - print(get_diff(contents, pretty_contents)) + print(get_diff(contents, list(pretty_contents))) if args.autofix: _autofix(json_file, pretty_contents) diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 3b7b9a24..bd844312 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -3,6 +3,7 @@ import pytest from six import PY2 +from pre_commit_hooks.pretty_format_json import get_diff from pre_commit_hooks.pretty_format_json import main from pre_commit_hooks.pretty_format_json import parse_num_to_int from testing.util import get_resource_path @@ -105,3 +106,78 @@ def test_top_sorted_get_pretty_format(): def test_badfile_main(): ret = main([get_resource_path('ok_yaml.yaml')]) assert ret == 1 + + +def test_diffing_output(): + table_tests = [ + { + 'name': 'diff_test_1', + 'source': """ +{ + "key1": "val1", + "key2": 2, +"array_key": [1, 2, 3], + "object":{ + "bool_key": true + } +} +""", + 'target': """ +{ + "array_key": [ + 1, + 2, + 3 + ], + "key1": "val1", + "key2": 2, + "object": { + "bool_key": true + } +} +""", + 'expected': """ +{ ++ "array_key": [ ++ 1, ++ 2, ++ 3 ++ ], +- "key1": "val1", +? -- + ++ "key1": "val1", +- "key2": 2, +? -- -- + ++ "key2": 2, +- "array_key": [1, 2, 3], +- "object":{ +? ------ + ++ "object": { +? + + +- "bool_key": true +? ---- + ++ "bool_key": true +- } ++ } + } +""", + }, + { + 'name': 'diff_test_2', + 'source': '', + 'target': '', + 'expected': '', + }, + + ] + for test in table_tests: + s = list(test['source']) + t = list(test['target']) + expected = test['expected'].strip() + actual = get_diff(s, t).strip() + assert actual == expected From 3de20fcd569664a25e08720302d39ad2ec7dc2ea Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 27 Aug 2019 21:28:13 -0700 Subject: [PATCH 049/334] Remove redundant flake8 dependency Committed via https://github.com/asottile/all-repos --- requirements-dev.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 2922ef5f..cf74d9f5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,6 @@ -e . coverage -flake8 mock pre-commit pytest From 0ff23d4e9fcaf66565206aa2a30cfdea53477f9d Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Fri, 13 Sep 2019 14:30:52 -0400 Subject: [PATCH 050/334] Remove extra cli flag, and update test case This commit uses capsys to test the output of the diff, which is now hidden behind the autofix flag if it's disabled --- pre_commit_hooks/pretty_format_json.py | 25 ++---- tests/pretty_format_json_test.py | 106 ++++++++++--------------- 2 files changed, 48 insertions(+), 83 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 2e04064a..3626332b 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -56,12 +56,12 @@ def parse_topkeys(s): # type: (str) -> List[str] return s.split(',') -def get_diff(source, target): # type: (List[str], List[str]) -> str - source_lines = ''.join(source).split('\n') - target_lines = ''.join(target).split('\n') - d = difflib.Differ() - diff = d.compare(source_lines, target_lines) - return '\n'.join(diff) +def get_diff(source, target): # type: (str, str) -> str + source_lines = source.splitlines(True) + target_lines = target.splitlines(True) + diff = ''.join(difflib.ndiff(source_lines, target_lines)) + print(diff) + return diff def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -105,14 +105,6 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int default=[], help='Ordered list of keys to keep at the top of JSON hashes', ) - parser.add_argument( - '--show-expected', - action='store_true', - dest='show_expected', - default=False, - help='Show a diff between the input file and expected (pretty) output', - ) - parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -131,11 +123,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if contents != pretty_contents: print('File {} is not pretty-formatted'.format(json_file)) - if args.show_expected: - print(get_diff(contents, list(pretty_contents))) - if args.autofix: _autofix(json_file, pretty_contents) + else: + print(get_diff(''.join(contents), pretty_contents)) status = 1 except ValueError: diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index bd844312..3aca1658 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -3,7 +3,6 @@ import pytest from six import PY2 -from pre_commit_hooks.pretty_format_json import get_diff from pre_commit_hooks.pretty_format_json import main from pre_commit_hooks.pretty_format_json import parse_num_to_int from testing.util import get_resource_path @@ -108,76 +107,51 @@ def test_badfile_main(): assert ret == 1 -def test_diffing_output(): - table_tests = [ - { - 'name': 'diff_test_1', - 'source': """ -{ - "key1": "val1", - "key2": 2, -"array_key": [1, 2, 3], - "object":{ - "bool_key": true - } -} -""", - 'target': """ -{ - "array_key": [ - 1, - 2, - 3 - ], - "key1": "val1", - "key2": 2, - "object": { - "bool_key": true +def test_diffing_output(capsys): + resource_path = get_resource_path('not_pretty_formatted_json.json') + expected_retval = 1 + expected_diff = ''' + { +- "foo": +- "bar", +- "alist": [2, 34, 234], ++ "alist": [ ++ 2, ++ 34, ++ 234 ++ ], +- "blah": null ++ "blah": null, +? + ++ "foo": "bar" } -} -""", - 'expected': """ -{ -+ "array_key": [ -+ 1, + + { +- "foo": +- "bar", +- "alist": [2, 34, 234], ++ "alist": [ + 2, -+ 3 ++ 34, ++ 234 + ], -- "key1": "val1", -? -- +- "blah": null ++ "blah": null, +? + ++ "foo": "bar" + } -+ "key1": "val1", -- "key2": 2, -? -- -- -+ "key2": 2, -- "array_key": [1, 2, 3], -- "object":{ -? ------ +''' + # output should include a line with the filepath, build it here + file_output_line = 'File {} is not pretty-formatted'.format(resource_path) + # prepend the above line to the diff + expected_output = file_output_line + expected_diff -+ "object": { -? + + actual_retval = main([resource_path]) + actual_output = capsys.readouterr() -- "bool_key": true -? ---- + assert actual_retval == expected_retval -+ "bool_key": true -- } -+ } - } -""", - }, - { - 'name': 'diff_test_2', - 'source': '', - 'target': '', - 'expected': '', - }, - - ] - for test in table_tests: - s = list(test['source']) - t = list(test['target']) - expected = test['expected'].strip() - actual = get_diff(s, t).strip() - assert actual == expected + actual_output = '\n'.join(actual_output) + assert actual_output == expected_output From 93b7b66cda7e00b2d9c7dd503a4fedbfa9802eaf Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Fri, 13 Sep 2019 14:38:40 -0400 Subject: [PATCH 051/334] Remove erroneoous print statement --- pre_commit_hooks/pretty_format_json.py | 1 - tests/pretty_format_json_test.py | 15 --------------- 2 files changed, 16 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 3626332b..8bf61c0e 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -60,7 +60,6 @@ def get_diff(source, target): # type: (str, str) -> str source_lines = source.splitlines(True) target_lines = target.splitlines(True) diff = ''.join(difflib.ndiff(source_lines, target_lines)) - print(diff) return diff diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 3aca1658..d95465d7 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -126,21 +126,6 @@ def test_diffing_output(capsys): + "foo": "bar" } - { -- "foo": -- "bar", -- "alist": [2, 34, 234], -+ "alist": [ -+ 2, -+ 34, -+ 234 -+ ], -- "blah": null -+ "blah": null, -? + -+ "foo": "bar" - } - ''' # output should include a line with the filepath, build it here From 831d2a99abca73bfe216617bb478723a1e2ed301 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Sun, 15 Sep 2019 12:51:03 -0400 Subject: [PATCH 052/334] Print file line stderr --- pre_commit_hooks/pretty_format_json.py | 5 ++++- tests/pretty_format_json_test.py | 17 ++++------------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 8bf61c0e..b9c0aa49 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -120,7 +120,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ) if contents != pretty_contents: - print('File {} is not pretty-formatted'.format(json_file)) + print( + 'File {} is not pretty-formatted'.format(json_file), + file=sys.stderr, + ) if args.autofix: _autofix(json_file, pretty_contents) diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index d95465d7..9c380a0a 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -108,10 +108,8 @@ def test_badfile_main(): def test_diffing_output(capsys): - resource_path = get_resource_path('not_pretty_formatted_json.json') expected_retval = 1 - expected_diff = ''' - { + expected_out = ''' { - "foo": - "bar", - "alist": [2, 34, 234], @@ -126,17 +124,10 @@ def test_diffing_output(capsys): + "foo": "bar" } - ''' - # output should include a line with the filepath, build it here - file_output_line = 'File {} is not pretty-formatted'.format(resource_path) - # prepend the above line to the diff - expected_output = file_output_line + expected_diff - actual_retval = main([resource_path]) - actual_output = capsys.readouterr() + actual_retval = main([get_resource_path('not_pretty_formatted_json.json')]) + out, err = capsys.readouterr() assert actual_retval == expected_retval - - actual_output = '\n'.join(actual_output) - assert actual_output == expected_output + assert out == expected_out From 35c76c4f33ec1d9fa4fafeedc90798d6338200fd Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Sun, 15 Sep 2019 12:54:03 -0400 Subject: [PATCH 053/334] Add test for std err --- tests/pretty_format_json_test.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 9c380a0a..3263b765 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -108,6 +108,7 @@ def test_badfile_main(): def test_diffing_output(capsys): + resource_path = get_resource_path('not_pretty_formatted_json.json') expected_retval = 1 expected_out = ''' { - "foo": @@ -125,9 +126,11 @@ def test_diffing_output(capsys): } ''' + expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) - actual_retval = main([get_resource_path('not_pretty_formatted_json.json')]) - out, err = capsys.readouterr() + actual_retval = main([resource_path]) + actual_out, actual_err = capsys.readouterr() assert actual_retval == expected_retval - assert out == expected_out + assert actual_out == expected_out + assert actual_err == expected_err From 27cd688c8eceae8946a1ea18ed5e8255fc9ed926 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Sun, 15 Sep 2019 13:29:52 -0400 Subject: [PATCH 054/334] Flush stderr, and formatting --- pre_commit_hooks/pretty_format_json.py | 1 + tests/pretty_format_json_test.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index b9c0aa49..3967c30d 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -124,6 +124,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int 'File {} is not pretty-formatted'.format(json_file), file=sys.stderr, ) + sys.stderr.flush() if args.autofix: _autofix(json_file, pretty_contents) diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 3263b765..04e4614f 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -110,7 +110,8 @@ def test_badfile_main(): def test_diffing_output(capsys): resource_path = get_resource_path('not_pretty_formatted_json.json') expected_retval = 1 - expected_out = ''' { + expected_out = '''\ + { - "foo": - "bar", - "alist": [2, 34, 234], From 31e740ed055dabb84c743d1e390d56b62f6e0264 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Sun, 15 Sep 2019 13:48:00 -0400 Subject: [PATCH 055/334] Use unified_diff --- pre_commit_hooks/pretty_format_json.py | 2 +- tests/pretty_format_json_test.py | 34 ++++++++++++++------------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 3967c30d..f5476a5f 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -59,7 +59,7 @@ def parse_topkeys(s): # type: (str) -> List[str] def get_diff(source, target): # type: (str, str) -> str source_lines = source.splitlines(True) target_lines = target.splitlines(True) - diff = ''.join(difflib.ndiff(source_lines, target_lines)) + diff = ''.join(difflib.unified_diff(source_lines, target_lines)) return diff diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 04e4614f..396c5e4d 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -111,22 +111,24 @@ def test_diffing_output(capsys): resource_path = get_resource_path('not_pretty_formatted_json.json') expected_retval = 1 expected_out = '''\ - { -- "foo": -- "bar", -- "alist": [2, 34, 234], -+ "alist": [ -+ 2, -+ 34, -+ 234 -+ ], -- "blah": null -+ "blah": null, -? + -+ "foo": "bar" - } - -''' +--- ++++ +@@ -1,6 +1,9 @@ + { +- "foo": +- "bar", +- "alist": [2, 34, 234], +- "blah": null ++ "alist": [ ++ 2, ++ 34, ++ 234 ++ ], ++ "blah": null, ++ "foo": "bar" + } + +''' # noqa: W291 expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) actual_retval = main([resource_path]) From 7d878b55ff2a0ddeb277b0545ee0c7f506b2a886 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Tue, 24 Sep 2019 15:21:45 -0400 Subject: [PATCH 056/334] Fix test cases for unified_diff --- tests/pretty_format_json_test.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 396c5e4d..d31fe91b 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -111,9 +111,7 @@ def test_diffing_output(capsys): resource_path = get_resource_path('not_pretty_formatted_json.json') expected_retval = 1 expected_out = '''\ ---- -+++ -@@ -1,6 +1,9 @@ +--- \n+++ \n@@ -1,6 +1,9 @@ { - "foo": - "bar", @@ -128,7 +126,7 @@ def test_diffing_output(capsys): + "foo": "bar" } -''' # noqa: W291 +''' expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) actual_retval = main([resource_path]) From ec6c39ee621461aa95e0cbcdd99189f331e31ce5 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Tue, 24 Sep 2019 15:42:24 -0400 Subject: [PATCH 057/334] Print filenames in the diff --- pre_commit_hooks/pretty_format_json.py | 16 +++++++++++----- tests/pretty_format_json_test.py | 13 +++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index f5476a5f..fa83305c 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -1,11 +1,11 @@ from __future__ import print_function import argparse -import difflib import io import json import sys from collections import OrderedDict +from difflib import unified_diff from typing import List from typing import Mapping from typing import Optional @@ -56,11 +56,11 @@ def parse_topkeys(s): # type: (str) -> List[str] return s.split(',') -def get_diff(source, target): # type: (str, str) -> str +def get_diff(source, target, file): # type: (str, str, str) -> str source_lines = source.splitlines(True) target_lines = target.splitlines(True) - diff = ''.join(difflib.unified_diff(source_lines, target_lines)) - return diff + diff = unified_diff(source_lines, target_lines, fromfile=file, tofile=file) + return ''.join(diff) def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -129,7 +129,13 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if args.autofix: _autofix(json_file, pretty_contents) else: - print(get_diff(''.join(contents), pretty_contents)) + print( + get_diff( + ''.join(contents), + pretty_contents, + json_file, + ), + ) status = 1 except ValueError: diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index d31fe91b..7020c4cf 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -1,3 +1,4 @@ +import os import shutil import pytest @@ -110,9 +111,13 @@ def test_badfile_main(): def test_diffing_output(capsys): resource_path = get_resource_path('not_pretty_formatted_json.json') expected_retval = 1 + a = os.path.join('a', resource_path) + b = os.path.join('b', resource_path) expected_out = '''\ ---- \n+++ \n@@ -1,6 +1,9 @@ - { +--- {} ++++ {} +@@ -1,6 +1,9 @@ + {{ - "foo": - "bar", - "alist": [2, 34, 234], @@ -124,9 +129,9 @@ def test_diffing_output(capsys): + ], + "blah": null, + "foo": "bar" - } + }} -''' +'''.format(a, b) expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) actual_retval = main([resource_path]) From ea8fbf9cf0d132a91af13729b766a3a31b8bfdac Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Tue, 24 Sep 2019 15:47:53 -0400 Subject: [PATCH 058/334] Remove unneeded string join --- pre_commit_hooks/pretty_format_json.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index fa83305c..642ed659 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -129,13 +129,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if args.autofix: _autofix(json_file, pretty_contents) else: - print( - get_diff( - ''.join(contents), - pretty_contents, - json_file, - ), - ) + print(get_diff(contents, pretty_contents, json_file)) status = 1 except ValueError: From d6c0aa5a3540a55e0fddb18870a308f96922e402 Mon Sep 17 00:00:00 2001 From: Joey Pinhas Date: Tue, 24 Sep 2019 16:27:34 -0400 Subject: [PATCH 059/334] Remove useless newline --- pre_commit_hooks/pretty_format_json.py | 5 ++++- tests/pretty_format_json_test.py | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 642ed659..cbc1b192 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -129,7 +129,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if args.autofix: _autofix(json_file, pretty_contents) else: - print(get_diff(contents, pretty_contents, json_file)) + print( + get_diff(contents, pretty_contents, json_file), + end='', + ) status = 1 except ValueError: diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 7020c4cf..6cfe772e 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -130,7 +130,6 @@ def test_diffing_output(capsys): + "blah": null, + "foo": "bar" }} - '''.format(a, b) expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) From da2ea3f7a7d6e6f88d43889fa2833aeddc902dfb Mon Sep 17 00:00:00 2001 From: "Barak Y. Reif" Date: Sat, 28 Sep 2019 21:40:09 +0300 Subject: [PATCH 060/334] add new line post reading requirements file, change before from tuple to list, add test cases --- pre_commit_hooks/requirements_txt_fixer.py | 9 +++++++-- tests/requirements_txt_fixer_test.py | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 4575975a..55744c65 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -40,9 +40,14 @@ def __lt__(self, requirement): # type: (Requirement) -> int def fix_requirements(f): # type: (IO[bytes]) -> int requirements = [] # type: List[Requirement] - before = tuple(f) + before = list(f) # type: List[bytes] after = [] # type: List[bytes] + # adds new line in case one is missing + # AND a change to the requirements file is needed regardless: + if before and not before[-1].endswith(b'\n'): + before[-1] += b'\n' + before_string = b''.join(before) # If the file is empty (i.e. only whitespace/newlines) exit early @@ -94,7 +99,7 @@ def fix_requirements(f): # type: (IO[bytes]) -> int after_string = b''.join(after) - if before_string == after_string: + if before_string.rstrip() == after_string.rstrip(): return PASS else: f.seek(0) diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index c7c6e47a..7c74ffc7 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -15,6 +15,9 @@ (b'foo\n# comment at end\n', PASS, b'foo\n# comment at end\n'), (b'foo\nbar\n', FAIL, b'bar\nfoo\n'), (b'bar\nfoo\n', PASS, b'bar\nfoo\n'), + (b'a\nc\nb\n', FAIL, b'a\nb\nc\n'), + (b'a\nc\nb', FAIL, b'a\nb\nc\n'), + (b'a\nb\nc', PASS, b'a\nb\nc'), ( b'#comment1\nfoo\n#comment2\nbar\n', FAIL, From d4b544daf399f2d356fbc8b0dccfe170ac18575b Mon Sep 17 00:00:00 2001 From: "Barak Y. Reif" Date: Sat, 28 Sep 2019 21:59:41 +0300 Subject: [PATCH 061/334] alter file with new line even if no other content is changed --- pre_commit_hooks/requirements_txt_fixer.py | 6 +++--- tests/requirements_txt_fixer_test.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 55744c65..1691d808 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -43,13 +43,13 @@ def fix_requirements(f): # type: (IO[bytes]) -> int before = list(f) # type: List[bytes] after = [] # type: List[bytes] + before_string = b''.join(before) + # adds new line in case one is missing # AND a change to the requirements file is needed regardless: if before and not before[-1].endswith(b'\n'): before[-1] += b'\n' - before_string = b''.join(before) - # If the file is empty (i.e. only whitespace/newlines) exit early if before_string.strip() == b'': return PASS @@ -99,7 +99,7 @@ def fix_requirements(f): # type: (IO[bytes]) -> int after_string = b''.join(after) - if before_string.rstrip() == after_string.rstrip(): + if before_string == after_string: return PASS else: f.seek(0) diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index 7c74ffc7..2e2eab65 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -17,7 +17,7 @@ (b'bar\nfoo\n', PASS, b'bar\nfoo\n'), (b'a\nc\nb\n', FAIL, b'a\nb\nc\n'), (b'a\nc\nb', FAIL, b'a\nb\nc\n'), - (b'a\nb\nc', PASS, b'a\nb\nc'), + (b'a\nb\nc', FAIL, b'a\nb\nc\n'), ( b'#comment1\nfoo\n#comment2\nbar\n', FAIL, From e4cfaa6b68dea4c4a66e30bda5f79b65755f7caf Mon Sep 17 00:00:00 2001 From: "Barak Y. Reif" Date: Sat, 28 Sep 2019 22:16:20 +0300 Subject: [PATCH 062/334] remove redundent type annotation --- pre_commit_hooks/requirements_txt_fixer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 1691d808..eff7935d 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -40,7 +40,7 @@ def __lt__(self, requirement): # type: (Requirement) -> int def fix_requirements(f): # type: (IO[bytes]) -> int requirements = [] # type: List[Requirement] - before = list(f) # type: List[bytes] + before = list(f) after = [] # type: List[bytes] before_string = b''.join(before) From d2a2cde37a56b87dd9edb91b3801b3f0a15153b5 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 7 Oct 2019 08:33:23 -0700 Subject: [PATCH 063/334] Add note about sort-simple-yaml's opt-in behaviour --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1950fa19..584b53d9 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,18 @@ Add this to your `.pre-commit-config.yaml` - `--no-sort-keys` - when autofixing, retain the original key ordering (instead of sorting the keys) - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. - `requirements-txt-fixer` - Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` -- `sort-simple-yaml` - Sorts simple YAML files which consist only of top-level keys, preserving comments and blocks. +- `sort-simple-yaml` - Sorts simple YAML files which consist only of top-level + keys, preserving comments and blocks. + + Note that `sort-simple-yaml` by default matches no `files` as it enforces a + very specific format. You must opt in to this by setting `files`, for + example: + + ```yaml + - id: sort-simple-yaml + files: ^config/simple/ + ``` + - `trailing-whitespace` - Trims trailing whitespace. - To preserve Markdown [hard linebreaks](https://github.github.com/gfm/#hard-line-break) use `args: [--markdown-linebreak-ext=md]` (or other extensions used From 86a010b750873ae00429f333c6e83ba7f8a7e29e Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 12 Oct 2019 13:39:15 -0700 Subject: [PATCH 064/334] Remove unnecessary double printing of filename --- pre_commit_hooks/pretty_format_json.py | 6 ------ tests/pretty_format_json_test.py | 4 +--- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index cbc1b192..7d515f47 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -120,12 +120,6 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ) if contents != pretty_contents: - print( - 'File {} is not pretty-formatted'.format(json_file), - file=sys.stderr, - ) - sys.stderr.flush() - if args.autofix: _autofix(json_file, pretty_contents) else: diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 6cfe772e..b42e504c 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -131,11 +131,9 @@ def test_diffing_output(capsys): + "foo": "bar" }} '''.format(a, b) - expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) - actual_retval = main([resource_path]) actual_out, actual_err = capsys.readouterr() assert actual_retval == expected_retval assert actual_out == expected_out - assert actual_err == expected_err + assert actual_err == '' From 886dfc42053f63ce64f382f3637f56919889979b Mon Sep 17 00:00:00 2001 From: iconmaster5326 Date: Fri, 25 Oct 2019 11:12:49 -0400 Subject: [PATCH 065/334] trailing-whitespace: add option for custom chars to strip --- pre_commit_hooks/trailing_whitespace_fixer.py | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 2ccc0038..88b3f930 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -7,10 +7,15 @@ from typing import Sequence -def _fix_file(filename, is_markdown): # type: (str, bool) -> bool +def _fix_file(filename, is_markdown, chars_to_strip): + # type: (str, bool, Optional[bytes]) -> bool with open(filename, mode='rb') as file_processed: lines = file_processed.readlines() - newlines = [_process_line(line, is_markdown) for line in lines] + newlines = [ + _process_line(line, is_markdown, chars_to_strip) + for line + in lines + ] if newlines != lines: with open(filename, mode='wb') as file_processed: for line in newlines: @@ -20,7 +25,8 @@ def _fix_file(filename, is_markdown): # type: (str, bool) -> bool return False -def _process_line(line, is_markdown): # type: (bytes, bool) -> bytes +def _process_line(line, is_markdown, chars_to_strip): + # type: (bytes, bool, Optional[bytes]) -> bytes if line[-2:] == b'\r\n': eol = b'\r\n' elif line[-1:] == b'\n': @@ -29,8 +35,8 @@ def _process_line(line, is_markdown): # type: (bytes, bool) -> bytes eol = b'' # preserve trailing two-space for non-blank lines in markdown files if is_markdown and (not line.isspace()) and line.endswith(b' ' + eol): - return line.rstrip() + b' ' + eol - return line.rstrip() + eol + return line.rstrip(chars_to_strip) + b' ' + eol + return line.rstrip(chars_to_strip) + eol def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -50,6 +56,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int 'default: %(default)s' ), ) + parser.add_argument( + '--chars', + help='The set of characters to strip from the end of lines. ' + 'Defaults to all whitespace characters.', + ) parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -78,7 +89,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for filename in args.filenames: _, extension = os.path.splitext(filename.lower()) md = all_markdown or extension in md_exts - if _fix_file(filename, md): + if _fix_file( + filename, + md, + None if args.chars is None else bytes(args.chars, 'utf-8'), + ): print('Fixing {}'.format(filename)) return_code = 1 return return_code From 08663c91f2362aa70fe0b5e9dc389823a46c66bf Mon Sep 17 00:00:00 2001 From: iconmaster5326 Date: Fri, 25 Oct 2019 11:15:48 -0400 Subject: [PATCH 066/334] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 584b53d9..e5799760 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,8 @@ Add this to your `.pre-commit-config.yaml` use `args: [--markdown-linebreak-ext=md]` (or other extensions used by your markdownfiles). If for some reason you want to treat all files as markdown, use `--markdown-linebreak-ext=*`. + - By default, this hook trims all whitespace from the ends of lines. + To specify a custom set of characters to trim instead, use `args: [--chars,""]`. ### Deprecated / replaced hooks From a2f836a23b095c19744fb5a73a3584cffa90bf8d Mon Sep 17 00:00:00 2001 From: iconmaster5326 Date: Fri, 25 Oct 2019 11:34:26 -0400 Subject: [PATCH 067/334] fix-whitespace: Added test for custom charsets --- pre_commit_hooks/trailing_whitespace_fixer.py | 6 ++++-- tests/trailing_whitespace_fixer_test.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 88b3f930..70ab3822 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -29,13 +29,15 @@ def _process_line(line, is_markdown, chars_to_strip): # type: (bytes, bool, Optional[bytes]) -> bytes if line[-2:] == b'\r\n': eol = b'\r\n' + line = line[:-2] elif line[-1:] == b'\n': eol = b'\n' + line = line[:-1] else: eol = b'' # preserve trailing two-space for non-blank lines in markdown files - if is_markdown and (not line.isspace()) and line.endswith(b' ' + eol): - return line.rstrip(chars_to_strip) + b' ' + eol + if is_markdown and (not line.isspace()) and line.endswith(b' '): + return line[:-2].rstrip(chars_to_strip) + b' ' + eol return line.rstrip(chars_to_strip) + eol diff --git a/tests/trailing_whitespace_fixer_test.py b/tests/trailing_whitespace_fixer_test.py index 82c9b6db..ec4c918b 100644 --- a/tests/trailing_whitespace_fixer_test.py +++ b/tests/trailing_whitespace_fixer_test.py @@ -78,3 +78,19 @@ def test_preserve_non_utf8_file(tmpdir): ret = main([path.strpath]) assert ret == 1 assert path.size() == (len(non_utf8_bytes_content) - 1) + + +def test_custom_charset_change(tmpdir): + # strip spaces only, no tabs + path = tmpdir.join('file.txt') + path.write('\ta \t \n') + ret = main([path.strpath, '--chars', ' ']) + assert ret == 1 + assert path.read() == '\ta \t\n' + + +def test_custom_charset_no_change(tmpdir): + path = tmpdir.join('file.txt') + path.write('\ta \t\n') + ret = main([path.strpath, '--chars', ' ']) + assert ret == 0 From c431f09ac30a903d74e47257bc3d1561a22f06e2 Mon Sep 17 00:00:00 2001 From: iconmaster5326 Date: Fri, 25 Oct 2019 11:54:00 -0400 Subject: [PATCH 068/334] Fix failure on Python 2 --- pre_commit_hooks/trailing_whitespace_fixer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 70ab3822..60636846 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -94,7 +94,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if _fix_file( filename, md, - None if args.chars is None else bytes(args.chars, 'utf-8'), + None if args.chars is None else bytes(args.chars.encode('utf-8')), ): print('Fixing {}'.format(filename)) return_code = 1 From dcbf43489c86a47ce0ec731c15613f7daf551181 Mon Sep 17 00:00:00 2001 From: Iconmaster Date: Fri, 25 Oct 2019 12:15:11 -0400 Subject: [PATCH 069/334] Apply suggestion: the `bytes(...)` call does nothing here --- pre_commit_hooks/trailing_whitespace_fixer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 60636846..b74b7530 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -94,7 +94,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if _fix_file( filename, md, - None if args.chars is None else bytes(args.chars.encode('utf-8')), + None if args.chars is None else args.chars.encode('utf-8'), ): print('Fixing {}'.format(filename)) return_code = 1 From a33a8f0d8aa87a1090427091182644dca880cb21 Mon Sep 17 00:00:00 2001 From: iconmaster5326 Date: Fri, 25 Oct 2019 12:20:04 -0400 Subject: [PATCH 070/334] Change parameter name to "chars" and move encoding outside loop --- pre_commit_hooks/trailing_whitespace_fixer.py | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index b74b7530..a21b54fc 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -7,15 +7,11 @@ from typing import Sequence -def _fix_file(filename, is_markdown, chars_to_strip): +def _fix_file(filename, is_markdown, chars): # type: (str, bool, Optional[bytes]) -> bool with open(filename, mode='rb') as file_processed: lines = file_processed.readlines() - newlines = [ - _process_line(line, is_markdown, chars_to_strip) - for line - in lines - ] + newlines = [_process_line(line, is_markdown, chars) for line in lines] if newlines != lines: with open(filename, mode='wb') as file_processed: for line in newlines: @@ -25,7 +21,7 @@ def _fix_file(filename, is_markdown, chars_to_strip): return False -def _process_line(line, is_markdown, chars_to_strip): +def _process_line(line, is_markdown, chars): # type: (bytes, bool, Optional[bytes]) -> bytes if line[-2:] == b'\r\n': eol = b'\r\n' @@ -37,8 +33,8 @@ def _process_line(line, is_markdown, chars_to_strip): eol = b'' # preserve trailing two-space for non-blank lines in markdown files if is_markdown and (not line.isspace()) and line.endswith(b' '): - return line[:-2].rstrip(chars_to_strip) + b' ' + eol - return line.rstrip(chars_to_strip) + eol + return line[:-2].rstrip(chars) + b' ' + eol + return line.rstrip(chars) + eol def main(argv=None): # type: (Optional[Sequence[str]]) -> int @@ -60,8 +56,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ) parser.add_argument( '--chars', - help='The set of characters to strip from the end of lines. ' - 'Defaults to all whitespace characters.', + help=( + 'The set of characters to strip from the end of lines. ' + 'Defaults to all whitespace characters.' + ), ) parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -86,16 +84,12 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int " (probably filename; use '--markdown-linebreak-ext=EXT')" .format(ext), ) - + chars = None if args.chars is None else args.chars.encode('utf-8') return_code = 0 for filename in args.filenames: _, extension = os.path.splitext(filename.lower()) md = all_markdown or extension in md_exts - if _fix_file( - filename, - md, - None if args.chars is None else args.chars.encode('utf-8'), - ): + if _fix_file(filename, md, chars): print('Fixing {}'.format(filename)) return_code = 1 return return_code From 0114962a7492186863997724384f6a77f09179f1 Mon Sep 17 00:00:00 2001 From: iconmaster5326 Date: Fri, 25 Oct 2019 12:28:50 -0400 Subject: [PATCH 071/334] Added test for --markdown-linebreak-ext and --chars together --- tests/trailing_whitespace_fixer_test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/trailing_whitespace_fixer_test.py b/tests/trailing_whitespace_fixer_test.py index ec4c918b..97f9aefe 100644 --- a/tests/trailing_whitespace_fixer_test.py +++ b/tests/trailing_whitespace_fixer_test.py @@ -94,3 +94,11 @@ def test_custom_charset_no_change(tmpdir): path.write('\ta \t\n') ret = main([path.strpath, '--chars', ' ']) assert ret == 0 + + +def test_markdown_with_custom_charset(tmpdir): + path = tmpdir.join('file.md') + path.write('\ta \t \n') + ret = main([path.strpath, '--chars', ' ', '--markdown-linebreak-ext', '*']) + assert ret == 1 + assert path.read() == '\ta \t \n' From 0161422b4e09b47536ea13f49e786eb3616fe0d7 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 28 Oct 2019 15:19:58 -0700 Subject: [PATCH 072/334] v2.4.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 17 +++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d4a3a1aa..7d156a11 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 + rev: v2.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d2c3642..d34a23ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +2.4.0 - 2019-10-28 +================== + +### Features +- Add diff output to `pretty-format-json` when run without `--autofix`. + - #408 PR by @joepin. +- Add `--chars` option to `trailing-whitespace` fixer to control which + characters are stripped instead of all whitespace. + - #421 PR by @iconmaster5326. + +### Fixes +- Fix `requirements-txt-fixer` when file does not end in a newline. + - #414 issue by @barakreif. + - #414 PR by @barakreif. +- Fix double printing of filename in `pretty-format-json`. + - #419 PR by @asottile. + 2.3.0 - 2019-08-05 ================== diff --git a/README.md b/README.md index e5799760..ec777453 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 # Use the ref you want to point at + rev: v2.4.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 4038836f..12c2b16e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.3.0 +version = 2.4.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From febac42f8e29fe90d6fc350184be494be3577c3f Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 28 Oct 2019 15:26:03 -0700 Subject: [PATCH 073/334] Fix PR number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d34a23ba..705a61a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ ### Fixes - Fix `requirements-txt-fixer` when file does not end in a newline. - #414 issue by @barakreif. - - #414 PR by @barakreif. + - #415 PR by @barakreif. - Fix double printing of filename in `pretty-format-json`. - #419 PR by @asottile. From 29f86dba1b78f857ab57e767d07d6cf2df42f45a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 28 Oct 2019 19:14:32 -0700 Subject: [PATCH 074/334] document --no-ensure-ascii --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ec777453..b0ea69b6 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ Add this to your `.pre-commit-config.yaml` the following commandline options: - `--autofix` - automatically format json files - `--indent ...` - Control the indentation (either a number for a number of spaces or a string of whitespace). Defaults to 4 spaces. + - `--no-ensure-ascii` preserve unicode characters instead of converting to escape sequences - `--no-sort-keys` - when autofixing, retain the original key ordering (instead of sorting the keys) - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. - `requirements-txt-fixer` - Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` From 189e33e48c92e8ad688e1ab2727a62b4dc490ae0 Mon Sep 17 00:00:00 2001 From: Vinay Karanam Date: Thu, 14 Nov 2019 02:22:07 +0530 Subject: [PATCH 075/334] Fixed sorting for non editable requirement urls --- pre_commit_hooks/requirements_txt_fixer.py | 5 +++-- tests/requirements_txt_fixer_test.py | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index eff7935d..1aa0dffa 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -21,8 +21,9 @@ def __init__(self): # type: () -> None @property def name(self): # type: () -> bytes assert self.value is not None, self.value - if self.value.startswith(b'-e '): - return self.value.lower().partition(b'=')[-1] + for egg in (b'#egg=', b'&egg='): + if egg in self.value: + return self.value.lower().partition(egg)[-1] return self.value.lower().partition(b'==')[0] diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index 2e2eab65..7b9b07d9 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -45,6 +45,11 @@ ), (b'bar\npkg-resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'), (b'foo\npkg-resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'), + ( + b'git+ssh://git_url@tag#egg=ocflib\nDjango\nijk\n', + FAIL, + b'Django\nijk\ngit+ssh://git_url@tag#egg=ocflib\n', + ), ), ) def test_integration(input_s, expected_retval, output, tmpdir): From 612a4b18cf943fdd01c64087b7c044e4ea61c71b Mon Sep 17 00:00:00 2001 From: Rich Rauenzahn Date: Wed, 4 Dec 2019 11:45:21 -0800 Subject: [PATCH 076/334] fix regular expression for test files --- pre_commit_hooks/tests_should_end_in_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py index 7a1e7c04..d93595f0 100644 --- a/pre_commit_hooks/tests_should_end_in_test.py +++ b/pre_commit_hooks/tests_should_end_in_test.py @@ -18,7 +18,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int args = parser.parse_args(argv) retcode = 0 - test_name_pattern = 'test.*.py' if args.django else '.*_test.py' + test_name_pattern = r'test.*\.py' if args.django else r'.*_test\.py' for filename in args.filenames: base = os.path.basename(filename) if ( From 3724c8f668b0c06a0d231d807ad3f90c6c89730d Mon Sep 17 00:00:00 2001 From: Rich Rauenzahn Date: Wed, 4 Dec 2019 15:06:32 -0800 Subject: [PATCH 077/334] add unit test for correct regex --- tests/tests_should_end_in_test_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/tests_should_end_in_test_test.py b/tests/tests_should_end_in_test_test.py index 2acfa177..4df2963f 100644 --- a/tests/tests_should_end_in_test_test.py +++ b/tests/tests_should_end_in_test_test.py @@ -11,6 +11,10 @@ def test_main_one_fails(): assert ret == 1 +def test_regex(): + assert main(('foo_test_py',)) == 1 + + def test_main_django_all_pass(): ret = main(( '--django', 'tests.py', 'test_foo.py', 'test_bar.py', From d25d0ed8ac08311e31287875a4457e6dd8435d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20B=C4=9Bl?= <35807926+mkbel@users.noreply.github.com> Date: Tue, 14 Jan 2020 22:44:59 +0100 Subject: [PATCH 078/334] Document mixed-line-ending limitation for fix={crlf,lf} with git. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b0ea69b6..fd62ffae 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Add this to your `.pre-commit-config.yaml` - `--fix={auto,crlf,lf,no}` - `auto` - Replaces automatically the most frequent line ending. This is the default argument. - `crlf`, `lf` - Forces to replace line ending by respectively CRLF and LF. + - This option isn't compatible with git setup check-in LF check-out CRLF as git smudge this later than the hook is invoked. - `no` - Checks if there is any mixed line ending without modifying any file. - `name-tests-test` - Assert that files in tests/ end in `_test.py`. - Use `args: ['--django']` to match `test*.py` instead. From e4dcfc650baaa355d4c71acee71108a86975faf4 Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Mon, 3 Feb 2020 14:10:31 +0100 Subject: [PATCH 079/334] Allow linking directly to each hook --- README.md | 60 +++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index fd62ffae..d7b68f9b 100644 --- a/README.md +++ b/README.md @@ -22,30 +22,30 @@ Add this to your `.pre-commit-config.yaml` ### Hooks available -- `check-added-large-files` - Prevent giant files from being committed. +- `check-added-large-files` - Prevent giant files from being committed. - Specify what is "too large" with `args: ['--maxkb=123']` (default=500kB). - If `git-lfs` is installed, lfs files will be skipped (requires `git-lfs>=2.2.1`) -- `check-ast` - Simply check whether files parse as valid python. -- `check-builtin-literals` - Require literal syntax when initializing empty or zero Python builtin types. +- `check-ast` - Simply check whether files parse as valid python. +- `check-builtin-literals` - Require literal syntax when initializing empty or zero Python builtin types. - Allows calling constructors with positional arguments (e.g., `list('abc')`). - Allows calling constructors from the `builtins` (`__builtin__`) namespace (`builtins.list()`). - Ignore this requirement for specific builtin types with `--ignore=type1,type2,…`. - Forbid `dict` keyword syntax with `--no-allow-dict-kwargs`. -- `check-byte-order-marker` - Forbid files which have a UTF-8 byte-order marker -- `check-case-conflict` - Check for files with names that would conflict on a +- `check-byte-order-marker` - Forbid files which have a UTF-8 byte-order marker +- `check-case-conflict` - Check for files with names that would conflict on a case-insensitive filesystem like MacOS HFS+ or Windows FAT. -- `check-docstring-first` - Checks for a common error of placing code before +- `check-docstring-first` - Checks for a common error of placing code before the docstring. -- `check-executables-have-shebangs` - Checks that non-binary executables have a +- `check-executables-have-shebangs` - Checks that non-binary executables have a proper shebang. -- `check-json` - Attempts to load all json files to verify syntax. -- `check-merge-conflict` - Check for files that contain merge conflict strings. -- `check-symlinks` - Checks for symlinks which do not point to anything. -- `check-toml` - Attempts to load all TOML files to verify syntax. -- `check-vcs-permalinks` - Ensures that links to vcs websites are permalinks. -- `check-xml` - Attempts to load all xml files to verify syntax. -- `check-yaml` - Attempts to load all yaml files to verify syntax. +- `check-json` - Attempts to load all json files to verify syntax. +- `check-merge-conflict` - Check for files that contain merge conflict strings. +- `check-symlinks` - Checks for symlinks which do not point to anything. +- `check-toml` - Attempts to load all TOML files to verify syntax. +- `check-vcs-permalinks` - Ensures that links to vcs websites are permalinks. +- `check-xml` - Attempts to load all xml files to verify syntax. +- `check-yaml` - Attempts to load all yaml files to verify syntax. - `--allow-multiple-documents` - allow yaml files which use the [multi-document syntax](http://www.yaml.org/spec/1.2/spec.html#YAML) - `--unsafe` - Instead of loading the files, simply parse them for syntax. @@ -53,9 +53,9 @@ Add this to your `.pre-commit-config.yaml` otherwise be forbidden. Using this option removes all guarantees of portability to other yaml implementations. Implies `--allow-multiple-documents`. -- `debug-statements` - Check for debugger imports and py37+ `breakpoint()` +- `debug-statements` - Check for debugger imports and py37+ `breakpoint()` calls in python source. -- `detect-aws-credentials` - Checks for the existence of AWS secrets that you +- `detect-aws-credentials` - Checks for the existence of AWS secrets that you have set up with the AWS CLI. The following arguments are available: - `--credentials-file CREDENTIALS_FILE` - additional AWS CLI style @@ -63,31 +63,31 @@ Add this to your `.pre-commit-config.yaml` credentials from. Can be repeated multiple times. - `--allow-missing-credentials` - Allow hook to pass when no credentials are detected. -- `detect-private-key` - Checks for the existence of private keys. -- `double-quote-string-fixer` - This hook replaces double quoted strings +- `detect-private-key` - Checks for the existence of private keys. +- `double-quote-string-fixer` - This hook replaces double quoted strings with single quoted strings. -- `end-of-file-fixer` - Makes sure files end in a newline and only a newline. -- `fix-encoding-pragma` - Add `# -*- coding: utf-8 -*-` to the top of python files. +- `end-of-file-fixer` - Makes sure files end in a newline and only a newline. +- `fix-encoding-pragma` - Add `# -*- coding: utf-8 -*-` to the top of python files. - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) -- `file-contents-sorter` - Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. Note that this hook WILL remove blank lines and does NOT respect any comments. -- `flake8` - Run flake8 on your python files. -- `forbid-new-submodules` - Prevent addition of new git submodules. -- `mixed-line-ending` - Replaces or checks mixed line ending. +- `file-contents-sorter` - Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. Note that this hook WILL remove blank lines and does NOT respect any comments. +- `flake8` - Run flake8 on your python files. +- `forbid-new-submodules` - Prevent addition of new git submodules. +- `mixed-line-ending` - Replaces or checks mixed line ending. - `--fix={auto,crlf,lf,no}` - `auto` - Replaces automatically the most frequent line ending. This is the default argument. - `crlf`, `lf` - Forces to replace line ending by respectively CRLF and LF. - This option isn't compatible with git setup check-in LF check-out CRLF as git smudge this later than the hook is invoked. - `no` - Checks if there is any mixed line ending without modifying any file. -- `name-tests-test` - Assert that files in tests/ end in `_test.py`. +- `name-tests-test` - Assert that files in tests/ end in `_test.py`. - Use `args: ['--django']` to match `test*.py` instead. -- `no-commit-to-branch` - Protect specific branches from direct checkins. +- `no-commit-to-branch` - Protect specific branches from direct checkins. - Use `args: [--branch, staging, --branch, master]` to set the branch. `master` is the default if no branch argument is set. - `-b` / `--branch` may be specified multiple times to protect multiple branches. - `-p` / `--pattern` can be used to protect branches that match a supplied regex (e.g. `--pattern, release/.*`). May be specified multiple times. -- `pretty-format-json` - Checks that all your JSON files are pretty. "Pretty" +- `pretty-format-json` - Checks that all your JSON files are pretty. "Pretty" here means that keys are sorted and indented. You can configure this with the following commandline options: - `--autofix` - automatically format json files @@ -95,8 +95,8 @@ Add this to your `.pre-commit-config.yaml` - `--no-ensure-ascii` preserve unicode characters instead of converting to escape sequences - `--no-sort-keys` - when autofixing, retain the original key ordering (instead of sorting the keys) - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. -- `requirements-txt-fixer` - Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` -- `sort-simple-yaml` - Sorts simple YAML files which consist only of top-level +- `requirements-txt-fixer` - Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` +- `sort-simple-yaml` - Sorts simple YAML files which consist only of top-level keys, preserving comments and blocks. Note that `sort-simple-yaml` by default matches no `files` as it enforces a @@ -108,7 +108,7 @@ Add this to your `.pre-commit-config.yaml` files: ^config/simple/ ``` -- `trailing-whitespace` - Trims trailing whitespace. +- `trailing-whitespace` - Trims trailing whitespace. - To preserve Markdown [hard linebreaks](https://github.github.com/gfm/#hard-line-break) use `args: [--markdown-linebreak-ext=md]` (or other extensions used by your markdownfiles). If for some reason you want to treat all files From fea76b9ea105f65961d3b9ba34686b6e591ec2c3 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 3 Feb 2020 08:41:48 -0800 Subject: [PATCH 080/334] Fix CI by upgrading AP templates --- .pre-commit-config.yaml | 14 +++++++------- azure-pipelines.yml | 2 +- pre_commit_hooks/check_ast.py | 17 +++++++++-------- pre_commit_hooks/check_merge_conflict.py | 8 +++++--- pre_commit_hooks/fix_encoding_pragma.py | 16 ++++++++++------ pre_commit_hooks/string_fixer.py | 5 ++--- pre_commit_hooks/util.py | 5 ++--- tests/check_builtin_literals_test.py | 6 +++--- 8 files changed, 39 insertions(+), 34 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d156a11..5a13dacc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,32 +13,32 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://gitlab.com/pycqa/flake8 - rev: 3.7.1 + rev: 3.7.9 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.4.3 + rev: v1.5 hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v1.14.2 + rev: v2.0.1 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports - rev: v1.3.5 + rev: v1.9.0 hooks: - id: reorder-python-imports language_version: python3 - repo: https://github.com/asottile/pyupgrade - rev: v1.11.1 + rev: v1.26.2 hooks: - id: pyupgrade - repo: https://github.com/asottile/add-trailing-comma - rev: v0.7.1 + rev: v1.5.0 hooks: - id: add-trailing-comma - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.660 + rev: v0.761 hooks: - id: mypy language_version: python3 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3156958c..1337dc63 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -10,7 +10,7 @@ resources: type: github endpoint: github name: asottile/azure-pipeline-templates - ref: refs/tags/v0.0.8 + ref: refs/tags/v1.0.0 jobs: - template: job--pre-commit.yml@asottile diff --git a/pre_commit_hooks/check_ast.py b/pre_commit_hooks/check_ast.py index 0df35407..cb33ea0b 100644 --- a/pre_commit_hooks/check_ast.py +++ b/pre_commit_hooks/check_ast.py @@ -23,14 +23,15 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int with open(filename, 'rb') as f: ast.parse(f.read(), filename=filename) except SyntaxError: - print('{}: failed parsing with {} {}:'.format( - filename, - platform.python_implementation(), - sys.version.partition(' ')[0], - )) - print('\n{}'.format( - ' ' + traceback.format_exc().replace('\n', '\n '), - )) + print( + '{}: failed parsing with {} {}:'.format( + filename, + platform.python_implementation(), + sys.version.partition(' ')[0], + ), + ) + tb = ' ' + traceback.format_exc().replace('\n', '\n ') + print('\n{}'.format(tb)) retval = 1 return retval diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index 74e4ae17..2a03c3a9 100644 --- a/pre_commit_hooks/check_merge_conflict.py +++ b/pre_commit_hooks/check_merge_conflict.py @@ -41,9 +41,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for i, line in enumerate(inputfile): for pattern in CONFLICT_PATTERNS: if line.startswith(pattern): - print(WARNING_MSG.format( - pattern.decode(), filename, i + 1, - )) + print( + WARNING_MSG.format( + pattern.decode(), filename, i + 1, + ), + ) retcode = 1 return retcode diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index 23fc79fd..31bb52c5 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -25,9 +25,11 @@ def has_coding(line): # type: (bytes) -> bool ) -class ExpectedContents(collections.namedtuple( - 'ExpectedContents', ('shebang', 'rest', 'pragma_status', 'ending'), -)): +class ExpectedContents( + collections.namedtuple( + 'ExpectedContents', ('shebang', 'rest', 'pragma_status', 'ending'), + ), +): """ pragma_status: - True: has exactly the coding pragma expected @@ -138,9 +140,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ) retv |= file_ret if file_ret: - print(fmt.format( - pragma=args.pragma.decode(), filename=filename, - )) + print( + fmt.format( + pragma=args.pragma.decode(), filename=filename, + ), + ) return retv diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py index a41b7373..813ef64e 100644 --- a/pre_commit_hooks/string_fixer.py +++ b/pre_commit_hooks/string_fixer.py @@ -45,9 +45,8 @@ def fix_strings(filename): # type: (str) -> int splitcontents = list(contents) # Iterate in reverse so the offsets are always correct - tokens = reversed(list(tokenize.generate_tokens( - io.StringIO(contents).readline, - ))) + tokens_l = list(tokenize.generate_tokens(io.StringIO(contents).readline)) + tokens = reversed(tokens_l) for token_type, token_text, (srow, scol), (erow, ecol), _ in tokens: if token_type == tokenize.STRING: new_text = handle_match(token_text) diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py index d68e7699..3b960e36 100644 --- a/pre_commit_hooks/util.py +++ b/pre_commit_hooks/util.py @@ -12,9 +12,8 @@ class CalledProcessError(RuntimeError): def added_files(): # type: () -> Set[str] - return set(cmd_output( - 'git', 'diff', '--staged', '--name-only', '--diff-filter=A', - ).splitlines()) + cmd = ('git', 'diff', '--staged', '--name-only', '--diff-filter=A') + return set(cmd_output(*cmd).splitlines()) def cmd_output(*cmd, **kwargs): # type: (*str, **Any) -> str diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py index 19263b79..8e18854f 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -121,9 +121,9 @@ def test_dict_no_allow_kwargs_exprs(expression, calls): def test_ignore_constructors(): - visitor = Visitor(ignore=( - 'complex', 'dict', 'float', 'int', 'list', 'str', 'tuple', - )) + visitor = Visitor( + ignore=('complex', 'dict', 'float', 'int', 'list', 'str', 'tuple'), + ) visitor.visit(ast.parse(BUILTIN_CONSTRUCTORS)) assert visitor.builtin_type_calls == [] From 3c614e7e0bbab61a0364f02172b0455432c411bb Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Tue, 4 Feb 2020 23:23:23 +0100 Subject: [PATCH 081/334] Convert named anchors to heading 4's --- README.md | 241 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 147 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index d7b68f9b..e13fbee0 100644 --- a/README.md +++ b/README.md @@ -22,99 +22,153 @@ Add this to your `.pre-commit-config.yaml` ### Hooks available -- `check-added-large-files` - Prevent giant files from being committed. - - Specify what is "too large" with `args: ['--maxkb=123']` (default=500kB). - - If `git-lfs` is installed, lfs files will be skipped - (requires `git-lfs>=2.2.1`) -- `check-ast` - Simply check whether files parse as valid python. -- `check-builtin-literals` - Require literal syntax when initializing empty or zero Python builtin types. - - Allows calling constructors with positional arguments (e.g., `list('abc')`). - - Allows calling constructors from the `builtins` (`__builtin__`) namespace (`builtins.list()`). - - Ignore this requirement for specific builtin types with `--ignore=type1,type2,…`. - - Forbid `dict` keyword syntax with `--no-allow-dict-kwargs`. -- `check-byte-order-marker` - Forbid files which have a UTF-8 byte-order marker -- `check-case-conflict` - Check for files with names that would conflict on a - case-insensitive filesystem like MacOS HFS+ or Windows FAT. -- `check-docstring-first` - Checks for a common error of placing code before - the docstring. -- `check-executables-have-shebangs` - Checks that non-binary executables have a - proper shebang. -- `check-json` - Attempts to load all json files to verify syntax. -- `check-merge-conflict` - Check for files that contain merge conflict strings. -- `check-symlinks` - Checks for symlinks which do not point to anything. -- `check-toml` - Attempts to load all TOML files to verify syntax. -- `check-vcs-permalinks` - Ensures that links to vcs websites are permalinks. -- `check-xml` - Attempts to load all xml files to verify syntax. -- `check-yaml` - Attempts to load all yaml files to verify syntax. - - `--allow-multiple-documents` - allow yaml files which use the - [multi-document syntax](http://www.yaml.org/spec/1.2/spec.html#YAML) - - `--unsafe` - Instead of loading the files, simply parse them for syntax. - A syntax-only check enables extensions and unsafe constructs which would - otherwise be forbidden. Using this option removes all guarantees of - portability to other yaml implementations. - Implies `--allow-multiple-documents`. -- `debug-statements` - Check for debugger imports and py37+ `breakpoint()` - calls in python source. -- `detect-aws-credentials` - Checks for the existence of AWS secrets that you - have set up with the AWS CLI. - The following arguments are available: - - `--credentials-file CREDENTIALS_FILE` - additional AWS CLI style - configuration file in a non-standard location to fetch configured - credentials from. Can be repeated multiple times. - - `--allow-missing-credentials` - Allow hook to pass when no credentials are - detected. -- `detect-private-key` - Checks for the existence of private keys. -- `double-quote-string-fixer` - This hook replaces double quoted strings +#### `check-added-large-files` +Prevent giant files from being committed. + - Specify what is "too large" with `args: ['--maxkb=123']` (default=500kB). + - If `git-lfs` is installed, lfs files will be skipped + (requires `git-lfs>=2.2.1`) + +#### `check-ast` +Simply check whether files parse as valid python. + +#### `check-builtin-literals` +Require literal syntax when initializing empty or zero Python builtin types. + - Allows calling constructors with positional arguments (e.g., `list('abc')`). + - Allows calling constructors from the `builtins` (`__builtin__`) namespace (`builtins.list()`). + - Ignore this requirement for specific builtin types with `--ignore=type1,type2,…`. + - Forbid `dict` keyword syntax with `--no-allow-dict-kwargs`. + +#### `check-byte-order-marker` +Forbid files which have a UTF-8 byte-order marker + +#### `check-case-conflict` +Check for files with names that would conflict on a case-insensitive filesystem like MacOS HFS+ or Windows FAT. + +#### `check-docstring-first` +Checks for a common error of placing code before the docstring. + +#### `check-executables-have-shebangs` +Checks that non-binary executables have a proper shebang. + +#### `check-json` +Attempts to load all json files to verify syntax. + +#### `check-merge-conflict` +Check for files that contain merge conflict strings. + +#### `check-symlinks` +Checks for symlinks which do not point to anything. + +#### `check-toml` +Attempts to load all TOML files to verify syntax. + +#### `check-vcs-permalinks` +Ensures that links to vcs websites are permalinks. + +#### `check-xml` +Attempts to load all xml files to verify syntax. + +#### `check-yaml` +Attempts to load all yaml files to verify syntax. + - `--allow-multiple-documents` - allow yaml files which use the + [multi-document syntax](http://www.yaml.org/spec/1.2/spec.html#YAML) + - `--unsafe` - Instead of loading the files, simply parse them for syntax. + A syntax-only check enables extensions and unsafe constructs which would + otherwise be forbidden. Using this option removes all guarantees of + portability to other yaml implementations. + Implies `--allow-multiple-documents`. + +#### `debug-statements` +Check for debugger imports and py37+ `breakpoint()` calls in python source. + +#### `detect-aws-credentials` +Checks for the existence of AWS secrets that you have set up with the AWS CLI. +The following arguments are available: +- `--credentials-file CREDENTIALS_FILE` - additional AWS CLI style + configuration file in a non-standard location to fetch configured + credentials from. Can be repeated multiple times. +- `--allow-missing-credentials` - Allow hook to pass when no credentials are detected. + +#### `detect-private-key` +Checks for the existence of private keys. + +#### `double-quote-string-fixer` +This hook replaces double quoted strings with single quoted strings. -- `end-of-file-fixer` - Makes sure files end in a newline and only a newline. -- `fix-encoding-pragma` - Add `# -*- coding: utf-8 -*-` to the top of python files. - - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) -- `file-contents-sorter` - Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. Note that this hook WILL remove blank lines and does NOT respect any comments. -- `flake8` - Run flake8 on your python files. -- `forbid-new-submodules` - Prevent addition of new git submodules. -- `mixed-line-ending` - Replaces or checks mixed line ending. - - `--fix={auto,crlf,lf,no}` - - `auto` - Replaces automatically the most frequent line ending. This is the default argument. - - `crlf`, `lf` - Forces to replace line ending by respectively CRLF and LF. - - This option isn't compatible with git setup check-in LF check-out CRLF as git smudge this later than the hook is invoked. - - `no` - Checks if there is any mixed line ending without modifying any file. -- `name-tests-test` - Assert that files in tests/ end in `_test.py`. - - Use `args: ['--django']` to match `test*.py` instead. -- `no-commit-to-branch` - Protect specific branches from direct checkins. - - Use `args: [--branch, staging, --branch, master]` to set the branch. - `master` is the default if no branch argument is set. - - `-b` / `--branch` may be specified multiple times to protect multiple - branches. - - `-p` / `--pattern` can be used to protect branches that match a supplied regex - (e.g. `--pattern, release/.*`). May be specified multiple times. -- `pretty-format-json` - Checks that all your JSON files are pretty. "Pretty" - here means that keys are sorted and indented. You can configure this with - the following commandline options: - - `--autofix` - automatically format json files - - `--indent ...` - Control the indentation (either a number for a number of spaces or a string of whitespace). Defaults to 4 spaces. - - `--no-ensure-ascii` preserve unicode characters instead of converting to escape sequences - - `--no-sort-keys` - when autofixing, retain the original key ordering (instead of sorting the keys) - - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. -- `requirements-txt-fixer` - Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` -- `sort-simple-yaml` - Sorts simple YAML files which consist only of top-level - keys, preserving comments and blocks. - - Note that `sort-simple-yaml` by default matches no `files` as it enforces a - very specific format. You must opt in to this by setting `files`, for - example: - - ```yaml - - id: sort-simple-yaml - files: ^config/simple/ - ``` - -- `trailing-whitespace` - Trims trailing whitespace. - - To preserve Markdown [hard linebreaks](https://github.github.com/gfm/#hard-line-break) - use `args: [--markdown-linebreak-ext=md]` (or other extensions used - by your markdownfiles). If for some reason you want to treat all files - as markdown, use `--markdown-linebreak-ext=*`. - - By default, this hook trims all whitespace from the ends of lines. - To specify a custom set of characters to trim instead, use `args: [--chars,""]`. + +#### `end-of-file-fixer` +Makes sure files end in a newline and only a newline. + +#### `fix-encoding-pragma` +Add `# -*- coding: utf-8 -*-` to the top of python files. + - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) + +#### `file-contents-sorter` +Sort the lines in specified files (defaults to alphabetical). +You must provide list of target files as input to it. +Note that this hook WILL remove blank lines and does NOT respect any comments. + +#### `flake8` +Run flake8 on your python files. + +#### `forbid-new-submodules` +Prevent addition of new git submodules. + +#### `mixed-line-ending` +Replaces or checks mixed line ending. + - `--fix={auto,crlf,lf,no}` + - `auto` - Replaces automatically the most frequent line ending. This is the default argument. + - `crlf`, `lf` - Forces to replace line ending by respectively CRLF and LF. + - This option isn't compatible with git setup check-in LF check-out CRLF as git smudge this later than the hook is invoked. + - `no` - Checks if there is any mixed line ending without modifying any file. + +#### `name-tests-test` +Assert that files in tests/ end in `_test.py`. + - Use `args: ['--django']` to match `test*.py` instead. + +#### `no-commit-to-branch` +Protect specific branches from direct checkins. + - Use `args: [--branch, staging, --branch, master]` to set the branch. + `master` is the default if no branch argument is set. + - `-b` / `--branch` may be specified multiple times to protect multiple + branches. + - `-p` / `--pattern` can be used to protect branches that match a supplied regex + (e.g. `--pattern, release/.*`). May be specified multiple times. + +#### `pretty-format-json` +Checks that all your JSON files are pretty. "Pretty" +here means that keys are sorted and indented. You can configure this with +the following commandline options: + - `--autofix` - automatically format json files + - `--indent ...` - Control the indentation (either a number for a number of spaces or a string of whitespace). Defaults to 4 spaces. + - `--no-ensure-ascii` preserve unicode characters instead of converting to escape sequences + - `--no-sort-keys` - when autofixing, retain the original key ordering (instead of sorting the keys) + - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. + +#### `requirements-txt-fixer` +Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` + +#### `sort-simple-yaml` +Sorts simple YAML files which consist only of top-level +keys, preserving comments and blocks. + +Note that `sort-simple-yaml` by default matches no `files` as it enforces a +very specific format. You must opt in to this by setting `files`, for example: + +```yaml + - id: sort-simple-yaml + files: ^config/simple/ +``` + + +#### `trailing-whitespace` +Trims trailing whitespace. + - To preserve Markdown [hard linebreaks](https://github.github.com/gfm/#hard-line-break) + use `args: [--markdown-linebreak-ext=md]` (or other extensions used + by your markdownfiles). If for some reason you want to treat all files + as markdown, use `--markdown-linebreak-ext=*`. + - By default, this hook trims all whitespace from the ends of lines. + To specify a custom set of characters to trim instead, use `args: [--chars,""]`. ### Deprecated / replaced hooks @@ -124,7 +178,6 @@ Add this to your `.pre-commit-config.yaml` ### As a standalone package -If you'd like to use these hooks, they're also available as a standalone -package. +If you'd like to use these hooks, they're also available as a standalone package. Simply `pip install pre-commit-hooks` From 96efcc6f85682a728ac9161ab1d5694c5108808c Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Tue, 4 Feb 2020 23:24:19 +0100 Subject: [PATCH 082/334] Remove linebreak --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e13fbee0..30f712df 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,7 @@ The following arguments are available: Checks for the existence of private keys. #### `double-quote-string-fixer` -This hook replaces double quoted strings - with single quoted strings. +This hook replaces double quoted strings with single quoted strings. #### `end-of-file-fixer` Makes sure files end in a newline and only a newline. From 810048551eadff50d03ac1e0a355a97e79161104 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 4 Feb 2020 15:59:37 -0800 Subject: [PATCH 083/334] officially deprecate the flake8 hook --- .pre-commit-hooks.yaml | 2 +- README.md | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 7a3b380a..666a2452 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -138,7 +138,7 @@ description: 'Add # -*- coding: utf-8 -*- to the top of python files' types: [python] - id: flake8 - name: Flake8 + name: Flake8 (deprecated, use gitlab.com/pycqa/flake8) description: This hook runs flake8. entry: flake8 language: python diff --git a/README.md b/README.md index 30f712df..ee62f2d2 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,6 @@ Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. Note that this hook WILL remove blank lines and does NOT respect any comments. -#### `flake8` -Run flake8 on your python files. - #### `forbid-new-submodules` Prevent addition of new git submodules. @@ -174,6 +171,7 @@ Trims trailing whitespace. - `autopep8-wrapper`: instead use [mirrors-autopep8](https://github.com/pre-commit/mirrors-autopep8) - `pyflakes`: instead use `flake8` +- `flake8`: instead use [upstream flake8](https://gitlab.com/pycqa/flake8) ### As a standalone package From 1057813c2ff113312dafe793061cdb100db67f54 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 4 Feb 2020 16:10:28 -0800 Subject: [PATCH 084/334] v2.5.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 19 +++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a13dacc..1bcc8c8a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.4.0 + rev: v2.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 705a61a0..a5fc902f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +2.5.0 - 2020-02-04 +================== + +### Fixes +- Fix sorting of requirements which use `egg=...` + - #425 PR by @vinayinvicible. +- Fix over-eager regular expression for test filename matching + - #429 PR by rrauenza. + +### Updating +- Use `flake8` from `pycqa/flake8` instead: + + ```yaml + - repo: https://gitlab.com/pycqa/flake8 + rev: 3.7.9 + hooks: + - id: flake8 + ``` + 2.4.0 - 2019-10-28 ================== diff --git a/README.md b/README.md index ee62f2d2..c98ba1b8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.4.0 # Use the ref you want to point at + rev: v2.5.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 12c2b16e..4b793f7f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.4.0 +version = 2.5.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 551d1a07b355e9497589ecba1922faabbc6f9316 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 4 Feb 2020 16:12:04 -0800 Subject: [PATCH 085/334] Fix mention in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5fc902f..24464936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - Fix sorting of requirements which use `egg=...` - #425 PR by @vinayinvicible. - Fix over-eager regular expression for test filename matching - - #429 PR by rrauenza. + - #429 PR by @rrauenza. ### Updating - Use `flake8` from `pycqa/flake8` instead: From f5c42a050bf7deef0d3fa7fde327c1ae3fd4bed1 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 5 Feb 2020 11:10:42 -0800 Subject: [PATCH 086/334] pre-commit-hooks: python3.6+ --- .pre-commit-config.yaml | 9 ++- azure-pipelines.yml | 4 +- pre_commit_hooks/autopep8_wrapper.py | 7 +- pre_commit_hooks/check_added_large_files.py | 19 ++---- pre_commit_hooks/check_ast.py | 18 ++--- pre_commit_hooks/check_builtin_literals.py | 49 +++++++------- pre_commit_hooks/check_byte_order_marker.py | 8 +-- pre_commit_hooks/check_case_conflict.py | 12 ++-- pre_commit_hooks/check_docstring_first.py | 39 +++-------- .../check_executables_have_shebangs.py | 22 +++--- pre_commit_hooks/check_json.py | 20 +++--- pre_commit_hooks/check_merge_conflict.py | 12 ++-- pre_commit_hooks/check_symlinks.py | 8 +-- pre_commit_hooks/check_toml.py | 9 +-- pre_commit_hooks/check_vcs_permalinks.py | 12 ++-- pre_commit_hooks/check_xml.py | 18 ++--- pre_commit_hooks/check_yaml.py | 24 +++---- pre_commit_hooks/debug_statement_hook.py | 35 +++++----- pre_commit_hooks/detect_aws_credentials.py | 33 ++++----- pre_commit_hooks/detect_private_key.py | 9 +-- pre_commit_hooks/end_of_file_fixer.py | 14 ++-- pre_commit_hooks/file_contents_sorter.py | 11 ++- pre_commit_hooks/fix_encoding_pragma.py | 67 +++++++++---------- pre_commit_hooks/forbid_new_submodules.py | 8 +-- pre_commit_hooks/mixed_line_ending.py | 16 ++--- pre_commit_hooks/no_commit_to_branch.py | 10 +-- pre_commit_hooks/pretty_format_json.py | 49 ++++++-------- pre_commit_hooks/requirements_txt_fixer.py | 26 +++---- pre_commit_hooks/sort_simple_yaml.py | 14 ++-- pre_commit_hooks/string_fixer.py | 18 ++--- pre_commit_hooks/tests_should_end_in_test.py | 13 +--- pre_commit_hooks/trailing_whitespace_fixer.py | 31 +++++---- pre_commit_hooks/util.py | 12 ++-- setup.cfg | 10 +-- testing/util.py | 3 - tests/autopep8_wrapper_test.py | 3 - tests/check_added_large_files_test.py | 7 +- tests/check_ast_test.py | 3 - tests/check_builtin_literals_test.py | 2 +- tests/check_byte_order_marker_test.py | 3 - tests/check_case_conflict_test.py | 3 - tests/check_docstring_first_test.py | 4 -- tests/check_executables_have_shebangs_test.py | 10 +-- tests/check_merge_conflict_test.py | 3 - tests/check_toml_test.py | 3 - tests/check_vcs_permalinks_test.py | 3 - tests/check_yaml_test.py | 3 - tests/conftest.py | 4 -- tests/debug_statement_hook_test.py | 4 -- tests/fix_encoding_pragma_test.py | 8 +-- tests/forbid_new_submodules_test.py | 2 - tests/mixed_line_ending_test.py | 7 +- tests/no_commit_to_branch_test.py | 3 - tests/pretty_format_json_test.py | 12 ++-- tests/readme_test.py | 11 +-- tests/sort_simple_yaml_test.py | 3 - tests/string_fixer_test.py | 4 -- tests/trailing_whitespace_fixer_test.py | 5 +- tests/util_test.py | 3 - tox.ini | 2 +- 60 files changed, 291 insertions(+), 493 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1bcc8c8a..464609be 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,17 +28,22 @@ repos: rev: v1.9.0 hooks: - id: reorder-python-imports - language_version: python3 + args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade rev: v1.26.2 hooks: - id: pyupgrade + args: [--py36-plus] - repo: https://github.com/asottile/add-trailing-comma rev: v1.5.0 hooks: - id: add-trailing-comma + args: [--py36-plus] +- repo: https://github.com/asottile/setup-cfg-fmt + rev: v1.6.0 + hooks: + - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.761 hooks: - id: mypy - language_version: python3 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1337dc63..dc3a57a9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -16,9 +16,9 @@ jobs: - template: job--pre-commit.yml@asottile - template: job--python-tox.yml@asottile parameters: - toxenvs: [py27, py37] + toxenvs: [py38] os: windows - template: job--python-tox.yml@asottile parameters: - toxenvs: [pypy, pypy3, py27, py36, py37] + toxenvs: [pypy3, py36, py37, py38] os: linux diff --git a/pre_commit_hooks/autopep8_wrapper.py b/pre_commit_hooks/autopep8_wrapper.py index 8b69a049..78a1cce8 100644 --- a/pre_commit_hooks/autopep8_wrapper.py +++ b/pre_commit_hooks/autopep8_wrapper.py @@ -1,9 +1,4 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - - -def main(): # type: () -> int +def main() -> int: raise SystemExit( 'autopep8-wrapper is deprecated. Instead use autopep8 directly via ' 'https://github.com/pre-commit/mirrors-autopep8', diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index be394989..91f57544 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -1,13 +1,7 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - import argparse import json import math import os -from typing import Iterable from typing import Optional from typing import Sequence from typing import Set @@ -17,7 +11,7 @@ from pre_commit_hooks.util import cmd_output -def lfs_files(): # type: () -> Set[str] +def lfs_files() -> Set[str]: try: # Introduced in git-lfs 2.2.0, first working in 2.2.1 lfs_ret = cmd_output('git', 'lfs', 'status', '--json') @@ -27,23 +21,20 @@ def lfs_files(): # type: () -> Set[str] return set(json.loads(lfs_ret)['files']) -def find_large_added_files(filenames, maxkb): - # type: (Iterable[str], int) -> int +def find_large_added_files(filenames: Sequence[str], maxkb: int) -> int: # Find all added files that are also in the list of files pre-commit tells # us about - filenames = (added_files() & set(filenames)) - lfs_files() - retv = 0 - for filename in filenames: + for filename in (added_files() & set(filenames)) - lfs_files(): kb = int(math.ceil(os.stat(filename).st_size / 1024)) if kb > maxkb: - print('{} ({} KB) exceeds {} KB.'.format(filename, kb, maxkb)) + print(f'{filename} ({kb} KB) exceeds {maxkb} KB.') retv = 1 return retv -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = 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 cb33ea0b..2be6e1af 100644 --- a/pre_commit_hooks/check_ast.py +++ b/pre_commit_hooks/check_ast.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse import ast import platform @@ -11,7 +7,7 @@ from typing import Sequence -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) @@ -23,15 +19,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int with open(filename, 'rb') as f: ast.parse(f.read(), filename=filename) except SyntaxError: - print( - '{}: failed parsing with {} {}:'.format( - filename, - platform.python_implementation(), - sys.version.partition(' ')[0], - ), - ) + impl = platform.python_implementation() + version = sys.version.split()[0] + print(f'{filename}: failed parsing with {impl} {version}:') tb = ' ' + traceback.format_exc().replace('\n', '\n ') - print('\n{}'.format(tb)) + print(f'\n{tb}') retval = 1 return retval diff --git a/pre_commit_hooks/check_builtin_literals.py b/pre_commit_hooks/check_builtin_literals.py index 4ddaa8c6..6bcd8387 100644 --- a/pre_commit_hooks/check_builtin_literals.py +++ b/pre_commit_hooks/check_builtin_literals.py @@ -1,10 +1,7 @@ -from __future__ import unicode_literals - import argparse import ast -import collections -import sys from typing import List +from typing import NamedTuple from typing import Optional from typing import Sequence from typing import Set @@ -21,23 +18,26 @@ } -Call = collections.namedtuple('Call', ['name', 'line', 'column']) +class Call(NamedTuple): + name: str + line: int + column: int class Visitor(ast.NodeVisitor): - def __init__(self, ignore=None, allow_dict_kwargs=True): - # type: (Optional[Sequence[str]], bool) -> None - self.builtin_type_calls = [] # type: List[Call] + def __init__( + self, + ignore: Optional[Sequence[str]] = None, + allow_dict_kwargs: bool = True, + ) -> None: + self.builtin_type_calls: List[Call] = [] self.ignore = set(ignore) if ignore else set() self.allow_dict_kwargs = allow_dict_kwargs - def _check_dict_call(self, node): # type: (ast.Call) -> bool - return ( - self.allow_dict_kwargs and - (getattr(node, 'kwargs', None) or getattr(node, 'keywords', None)) - ) + def _check_dict_call(self, node: ast.Call) -> bool: + return self.allow_dict_kwargs and bool(node.keywords) - def visit_Call(self, node): # type: (ast.Call) -> None + def visit_Call(self, node: ast.Call) -> None: if not isinstance(node.func, ast.Name): # Ignore functions that are object attributes (`foo.bar()`). # Assume that if the user calls `builtins.list()`, they know what @@ -54,8 +54,11 @@ def visit_Call(self, node): # type: (ast.Call) -> None ) -def check_file(filename, ignore=None, allow_dict_kwargs=True): - # type: (str, Optional[Sequence[str]], bool) -> List[Call] +def check_file( + filename: str, + ignore: Optional[Sequence[str]] = None, + allow_dict_kwargs: bool = True, +) -> 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) @@ -63,11 +66,11 @@ def check_file(filename, ignore=None, allow_dict_kwargs=True): return visitor.builtin_type_calls -def parse_ignore(value): # type: (str) -> Set[str] +def parse_ignore(value: str) -> Set[str]: return set(value.split(',')) -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') parser.add_argument('--ignore', type=parse_ignore, default=set()) @@ -93,15 +96,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int rc = rc or 1 for call in calls: print( - '{filename}:{call.line}:{call.column}: ' - 'replace {call.name}() with {replacement}'.format( - filename=filename, - call=call, - replacement=BUILTIN_TYPES[call.name], - ), + f'{filename}:{call.line}:{call.column}: ' + f'replace {call.name}() with {BUILTIN_TYPES[call.name]}', ) return rc if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/check_byte_order_marker.py b/pre_commit_hooks/check_byte_order_marker.py index 10667c33..c0c2969c 100644 --- a/pre_commit_hooks/check_byte_order_marker.py +++ b/pre_commit_hooks/check_byte_order_marker.py @@ -1,13 +1,9 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse from typing import Optional from typing import Sequence -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to check') args = parser.parse_args(argv) @@ -18,7 +14,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int with open(filename, 'rb') as f: if f.read(3) == b'\xef\xbb\xbf': retv = 1 - print('{}: Has a byte-order marker'.format(filename)) + print(f'{filename}: Has a byte-order marker') return retv diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py index e343d61f..6b8ba82f 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse from typing import Iterable from typing import Optional @@ -12,11 +8,11 @@ from pre_commit_hooks.util import cmd_output -def lower_set(iterable): # type: (Iterable[str]) -> Set[str] +def lower_set(iterable: Iterable[str]) -> Set[str]: return {x.lower() for x in iterable} -def find_conflicting_filenames(filenames): # type: (Sequence[str]) -> int +def find_conflicting_filenames(filenames: Sequence[str]) -> int: repo_files = set(cmd_output('git', 'ls-files').splitlines()) relevant_files = set(filenames) | added_files() repo_files -= relevant_files @@ -39,13 +35,13 @@ def find_conflicting_filenames(filenames): # type: (Sequence[str]) -> int if x.lower() in conflicts ] for filename in sorted(conflicting_files): - print('Case-insensitivity conflict found: {}'.format(filename)) + print(f'Case-insensitivity conflict found: {filename}') retv = 1 return retv -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = 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 6c19381c..875c0fba 100644 --- a/pre_commit_hooks/check_docstring_first.py +++ b/pre_commit_hooks/check_docstring_first.py @@ -1,30 +1,17 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse import io import tokenize +from tokenize import tokenize as tokenize_tokenize from typing import Optional from typing import Sequence -import six - -if six.PY2: # pragma: no cover (PY2) - from tokenize import generate_tokens as tokenize_tokenize - OTHER_NON_CODE = () -else: # pragma: no cover (PY3) - from tokenize import tokenize as tokenize_tokenize - OTHER_NON_CODE = (tokenize.ENCODING,) - -NON_CODE_TOKENS = frozenset( - (tokenize.COMMENT, tokenize.ENDMARKER, tokenize.NEWLINE, tokenize.NL) + - OTHER_NON_CODE, -) +NON_CODE_TOKENS = frozenset(( + tokenize.COMMENT, tokenize.ENDMARKER, tokenize.NEWLINE, tokenize.NL, + tokenize.ENCODING, +)) -def check_docstring_first(src, filename=''): - # type: (bytes, str) -> int +def check_docstring_first(src: bytes, filename: str = '') -> int: """Returns nonzero if the source has what looks like a docstring that is not at the beginning of the source. @@ -40,18 +27,14 @@ def check_docstring_first(src, filename=''): if tok_type == tokenize.STRING and scol == 0: if found_docstring_line is not None: print( - '{}:{} Multiple module docstrings ' - '(first docstring on line {}).'.format( - filename, sline, found_docstring_line, - ), + f'{filename}:{sline} Multiple module docstrings ' + f'(first docstring on line {found_docstring_line}).', ) return 1 elif found_code_line is not None: print( - '{}:{} Module docstring appears after code ' - '(code seen on line {}).'.format( - filename, sline, found_code_line, - ), + f'{filename}:{sline} Module docstring appears after code ' + f'(code seen on line {found_code_line}).', ) return 1 else: @@ -62,7 +45,7 @@ def check_docstring_first(src, filename=''): return 0 -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = 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 4db2f9fb..c34c7b70 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -1,28 +1,22 @@ """Check that executable text files have a shebang.""" -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse -import pipes +import shlex import sys from typing import Optional from typing import Sequence -def check_has_shebang(path): # type: (str) -> int +def check_has_shebang(path: str) -> int: with open(path, 'rb') as f: first_bytes = f.read(2) if first_bytes != b'#!': + quoted = shlex.quote(path) print( - '{path}: marked executable but has no (or invalid) shebang!\n' - " If it isn't supposed to be executable, try: chmod -x {quoted}\n" - ' If it is supposed to be executable, double-check its shebang.' - .format( - path=path, - quoted=pipes.quote(path), - ), + f'{path}: marked executable but has no (or invalid) shebang!\n' + f" If it isn't supposed to be executable, try: " + f'`chmod -x {quoted}`\n' + f' If it is supposed to be executable, double-check its shebang.', file=sys.stderr, ) return 1 @@ -30,7 +24,7 @@ def check_has_shebang(path): # type: (str) -> int return 0 -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = 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 f26e0a5b..25dbfd95 100644 --- a/pre_commit_hooks/check_json.py +++ b/pre_commit_hooks/check_json.py @@ -1,27 +1,25 @@ -from __future__ import print_function - import argparse -import io import json -import sys from typing import Optional from typing import Sequence -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to check.') args = parser.parse_args(argv) retval = 0 for filename in args.filenames: - try: - json.load(io.open(filename, encoding='UTF-8')) - except (ValueError, UnicodeDecodeError) as exc: - print('{}: Failed to json decode ({})'.format(filename, exc)) - retval = 1 + with open(filename, 'rb') as f: + try: + json.load(f) + # TODO: need UnicodeDecodeError? + except (ValueError, UnicodeDecodeError) as exc: + print(f'{filename}: Failed to json decode ({exc})') + retval = 1 return retval if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index 2a03c3a9..c20a8af7 100644 --- a/pre_commit_hooks/check_merge_conflict.py +++ b/pre_commit_hooks/check_merge_conflict.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import argparse import os.path from typing import Optional @@ -12,10 +10,9 @@ b'=======\n', b'>>>>>>> ', ] -WARNING_MSG = 'Merge conflict string "{0}" found in {1}:{2}' -def is_in_merge(): # type: () -> int +def is_in_merge() -> int: return ( os.path.exists(os.path.join('.git', 'MERGE_MSG')) and ( @@ -26,7 +23,7 @@ def is_in_merge(): # type: () -> int ) -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') parser.add_argument('--assume-in-merge', action='store_true') @@ -42,9 +39,8 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for pattern in CONFLICT_PATTERNS: if line.startswith(pattern): print( - WARNING_MSG.format( - pattern.decode(), filename, i + 1, - ), + f'Merge conflict string "{pattern.decode()}" ' + f'found in {filename}:{i + 1}', ) retcode = 1 diff --git a/pre_commit_hooks/check_symlinks.py b/pre_commit_hooks/check_symlinks.py index 736bf99c..f014714a 100644 --- a/pre_commit_hooks/check_symlinks.py +++ b/pre_commit_hooks/check_symlinks.py @@ -1,14 +1,10 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse import os.path from typing import Optional from typing import Sequence -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser(description='Checks for broken symlinks.') parser.add_argument('filenames', nargs='*', help='Filenames to check') args = parser.parse_args(argv) @@ -20,7 +16,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int os.path.islink(filename) and not os.path.exists(filename) ): # pragma: no cover (symlink support required) - print('{}: Broken symlink'.format(filename)) + print(f'{filename}: Broken symlink') retv = 1 return retv diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py index e16e17c9..51a1f15e 100644 --- a/pre_commit_hooks/check_toml.py +++ b/pre_commit_hooks/check_toml.py @@ -1,14 +1,11 @@ -from __future__ import print_function - import argparse -import sys from typing import Optional from typing import Sequence import toml -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to check.') args = parser.parse_args(argv) @@ -19,10 +16,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int with open(filename) as f: toml.load(f) except toml.TomlDecodeError as exc: - print('{}: {}'.format(filename, exc)) + print(f'{filename}: {exc}') retval = 1 return retval if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/check_vcs_permalinks.py b/pre_commit_hooks/check_vcs_permalinks.py index f6e2a7d5..bf698e11 100644 --- a/pre_commit_hooks/check_vcs_permalinks.py +++ b/pre_commit_hooks/check_vcs_permalinks.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse import re import sys @@ -14,19 +10,19 @@ ) -def _check_filename(filename): # type: (str) -> int +def _check_filename(filename: str) -> int: retv = 0 with open(filename, 'rb') as f: for i, line in enumerate(f, 1): if GITHUB_NON_PERMALINK.search(line): - sys.stdout.write('{}:{}:'.format(filename, i)) + sys.stdout.write(f'{filename}:{i}:') sys.stdout.flush() - getattr(sys.stdout, 'buffer', sys.stdout).write(line) + sys.stdout.buffer.write(line) retv = 1 return retv -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py index 66e10bac..eddfdf99 100644 --- a/pre_commit_hooks/check_xml.py +++ b/pre_commit_hooks/check_xml.py @@ -1,30 +1,26 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse -import io -import sys import xml.sax.handler from typing import Optional from typing import Sequence -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='XML filenames to check.') args = parser.parse_args(argv) retval = 0 + handler = xml.sax.handler.ContentHandler() for filename in args.filenames: try: - with io.open(filename, 'rb') as xml_file: - xml.sax.parse(xml_file, xml.sax.handler.ContentHandler()) + with open(filename, 'rb') as xml_file: + # https://github.com/python/typeshed/pull/3725 + xml.sax.parse(xml_file, handler) # type: ignore except xml.sax.SAXException as exc: - print('{}: Failed to xml parse ({})'.format(filename, exc)) + print(f'{filename}: Failed to xml parse ({exc})') retval = 1 return retval if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 5b664854..7453f6fb 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -1,11 +1,7 @@ -from __future__ import print_function - import argparse -import collections -import io -import sys from typing import Any from typing import Generator +from typing import NamedTuple from typing import Optional from typing import Sequence @@ -14,20 +10,24 @@ yaml = ruamel.yaml.YAML(typ='safe') -def _exhaust(gen): # type: (Generator[str, None, None]) -> None +def _exhaust(gen: Generator[str, None, None]) -> None: for _ in gen: pass -def _parse_unsafe(*args, **kwargs): # type: (*Any, **Any) -> None +def _parse_unsafe(*args: Any, **kwargs: Any) -> None: _exhaust(yaml.parse(*args, **kwargs)) -def _load_all(*args, **kwargs): # type: (*Any, **Any) -> None +def _load_all(*args: Any, **kwargs: Any) -> None: _exhaust(yaml.load_all(*args, **kwargs)) -Key = collections.namedtuple('Key', ('multi', 'unsafe')) +class Key(NamedTuple): + multi: bool + unsafe: bool + + LOAD_FNS = { Key(multi=False, unsafe=False): yaml.load, Key(multi=False, unsafe=True): _parse_unsafe, @@ -36,7 +36,7 @@ def _load_all(*args, **kwargs): # type: (*Any, **Any) -> None } -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument( '-m', '--multi', '--allow-multiple-documents', action='store_true', @@ -59,7 +59,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int retval = 0 for filename in args.filenames: try: - with io.open(filename, encoding='UTF-8') as f: + with open(filename, encoding='UTF-8') as f: load_fn(f) except ruamel.yaml.YAMLError as exc: print(exc) @@ -68,4 +68,4 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 48648734..00423ac8 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -1,35 +1,38 @@ -from __future__ import print_function -from __future__ import unicode_literals - import argparse import ast -import collections import traceback from typing import List +from typing import NamedTuple from typing import Optional from typing import Sequence DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb', 'rpdb'} -Debug = collections.namedtuple('Debug', ('line', 'col', 'name', 'reason')) + + +class Debug(NamedTuple): + line: int + col: int + name: str + reason: str class DebugStatementParser(ast.NodeVisitor): - def __init__(self): # type: () -> None - self.breakpoints = [] # type: List[Debug] + def __init__(self) -> None: + self.breakpoints: List[Debug] = [] - def visit_Import(self, node): # type: (ast.Import) -> None + def visit_Import(self, node: ast.Import) -> None: for name in node.names: if name.name in DEBUG_STATEMENTS: st = Debug(node.lineno, node.col_offset, name.name, 'imported') self.breakpoints.append(st) - def visit_ImportFrom(self, node): # type: (ast.ImportFrom) -> None + def visit_ImportFrom(self, node: ast.ImportFrom) -> None: if node.module in DEBUG_STATEMENTS: st = Debug(node.lineno, node.col_offset, node.module, 'imported') self.breakpoints.append(st) - def visit_Call(self, node): # type: (ast.Call) -> None + def visit_Call(self, node: ast.Call) -> None: """python3.7+ breakpoint()""" if isinstance(node.func, ast.Name) and node.func.id == 'breakpoint': st = Debug(node.lineno, node.col_offset, node.func.id, 'called') @@ -37,12 +40,12 @@ def visit_Call(self, node): # type: (ast.Call) -> None self.generic_visit(node) -def check_file(filename): # type: (str) -> int +def check_file(filename: str) -> int: try: with open(filename, 'rb') as f: ast_obj = ast.parse(f.read(), filename=filename) except SyntaxError: - print('{} - Could not parse ast'.format(filename)) + print(f'{filename} - Could not parse ast') print() print('\t' + traceback.format_exc().replace('\n', '\n\t')) print() @@ -52,16 +55,12 @@ def check_file(filename): # type: (str) -> int visitor.visit(ast_obj) for bp in visitor.breakpoints: - print( - '{}:{}:{} - {} {}'.format( - filename, bp.line, bp.col, bp.name, bp.reason, - ), - ) + print(f'{filename}:{bp.line}:{bp.col} - {bp.name} {bp.reason}') return int(bool(visitor.breakpoints)) -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = 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/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index da80ab4f..fe18f4df 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -1,18 +1,19 @@ -from __future__ import print_function -from __future__ import unicode_literals - import argparse +import configparser import os -from typing import Dict from typing import List +from typing import NamedTuple from typing import Optional from typing import Sequence from typing import Set -from six.moves import configparser + +class BadFile(NamedTuple): + filename: str + key: str -def get_aws_cred_files_from_env(): # type: () -> Set[str] +def get_aws_cred_files_from_env() -> Set[str]: """Extract credential file paths from environment variables.""" return { os.environ[env_var] @@ -24,7 +25,7 @@ def get_aws_cred_files_from_env(): # type: () -> Set[str] } -def get_aws_secrets_from_env(): # type: () -> Set[str] +def get_aws_secrets_from_env() -> Set[str]: """Extract AWS secrets from environment variables.""" keys = set() for env_var in ( @@ -35,7 +36,7 @@ def get_aws_secrets_from_env(): # type: () -> Set[str] return keys -def get_aws_secrets_from_file(credentials_file): # type: (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 @@ -66,8 +67,10 @@ def get_aws_secrets_from_file(credentials_file): # type: (str) -> Set[str] return keys -def check_file_for_aws_keys(filenames, keys): - # type: (Sequence[str], Set[str]) -> List[Dict[str, str]] +def check_file_for_aws_keys( + filenames: Sequence[str], + keys: Set[str], +) -> List[BadFile]: """Check if files contain AWS secrets. Return a list of all files containing AWS secrets and keys found, with all @@ -82,13 +85,11 @@ def check_file_for_aws_keys(filenames, keys): # naively match the entire file, low chance of incorrect # collision if key in text_body: - bad_files.append({ - 'filename': filename, 'key': key[:4] + '*' * 28, - }) + bad_files.append(BadFile(filename, key[:4].ljust(28, '*'))) return bad_files -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='+', help='Filenames to run') parser.add_argument( @@ -117,7 +118,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int # of files to to gather AWS secrets from. credential_files |= get_aws_cred_files_from_env() - keys = set() # type: Set[str] + keys: Set[str] = set() for credential_file in credential_files: keys |= get_aws_secrets_from_file(credential_file) @@ -139,7 +140,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int bad_filenames = check_file_for_aws_keys(args.filenames, keys) if bad_filenames: for bad_file in bad_filenames: - print('AWS secret found in {filename}: {key}'.format(**bad_file)) + print(f'AWS secret found in {bad_file.filename}: {bad_file.key}') return 1 else: return 0 diff --git a/pre_commit_hooks/detect_private_key.py b/pre_commit_hooks/detect_private_key.py index d31957de..7bbc2f91 100644 --- a/pre_commit_hooks/detect_private_key.py +++ b/pre_commit_hooks/detect_private_key.py @@ -1,7 +1,4 @@ -from __future__ import print_function - import argparse -import sys from typing import Optional from typing import Sequence @@ -17,7 +14,7 @@ ] -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to check') args = parser.parse_args(argv) @@ -32,11 +29,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if private_key_files: for private_key_file in private_key_files: - print('Private key found: {}'.format(private_key_file)) + print(f'Private key found: {private_key_file}') return 1 else: return 0 if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/end_of_file_fixer.py b/pre_commit_hooks/end_of_file_fixer.py index 4e77c945..1c07379d 100644 --- a/pre_commit_hooks/end_of_file_fixer.py +++ b/pre_commit_hooks/end_of_file_fixer.py @@ -1,20 +1,16 @@ -from __future__ import print_function -from __future__ import unicode_literals - import argparse import os -import sys from typing import IO from typing import Optional from typing import Sequence -def fix_file(file_obj): # type: (IO[bytes]) -> int +def fix_file(file_obj: IO[bytes]) -> int: # Test for newline at end of file # Empty files will throw IOError here try: file_obj.seek(-1, os.SEEK_END) - except IOError: + except OSError: return 0 last_character = file_obj.read(1) # last_character will be '' for an empty file @@ -52,7 +48,7 @@ def fix_file(file_obj): # type: (IO[bytes]) -> int return 0 -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -64,11 +60,11 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int with open(filename, 'rb+') as file_obj: ret_for_file = fix_file(file_obj) if ret_for_file: - print('Fixing {}'.format(filename)) + print(f'Fixing {filename}') retv |= ret_for_file return retv if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 1598d2da..41ce306f 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -9,10 +9,7 @@ this hook on that file should reduce the instances of git merge conflicts and keep the file nicely ordered. """ -from __future__ import print_function - import argparse -import sys from typing import IO from typing import Optional from typing import Sequence @@ -21,7 +18,7 @@ FAIL = 1 -def sort_file_contents(f): # type: (IO[bytes]) -> int +def sort_file_contents(f: IO[bytes]) -> int: before = list(f) after = sorted([line.strip(b'\n\r') for line in before if line.strip()]) @@ -37,7 +34,7 @@ def sort_file_contents(f): # type: (IO[bytes]) -> int return FAIL -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='+', help='Files to sort') args = parser.parse_args(argv) @@ -49,7 +46,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ret_for_file = sort_file_contents(file_obj) if ret_for_file: - print('Sorting {}'.format(arg)) + print(f'Sorting {arg}') retv |= ret_for_file @@ -57,4 +54,4 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index 31bb52c5..88d72ed7 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -1,18 +1,13 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse -import collections from typing import IO +from typing import NamedTuple from typing import Optional from typing import Sequence -from typing import Union DEFAULT_PRAGMA = b'# -*- coding: utf-8 -*-' -def has_coding(line): # type: (bytes) -> bool +def has_coding(line: bytes) -> bool: if not line.strip(): return False return ( @@ -25,30 +20,30 @@ def has_coding(line): # type: (bytes) -> bool ) -class ExpectedContents( - collections.namedtuple( - 'ExpectedContents', ('shebang', 'rest', 'pragma_status', 'ending'), - ), -): - """ - pragma_status: - - True: has exactly the coding pragma expected - - False: missing coding pragma entirely - - None: has a coding pragma, but it does not match - """ - __slots__ = () +class ExpectedContents(NamedTuple): + shebang: bytes + rest: bytes + # 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] + ending: bytes @property - def has_any_pragma(self): # type: () -> bool + def has_any_pragma(self) -> bool: return self.pragma_status is not False - def is_expected_pragma(self, remove): # type: (bool) -> bool + def is_expected_pragma(self, remove: bool) -> bool: expected_pragma_status = not remove return self.pragma_status is expected_pragma_status -def _get_expected_contents(first_line, second_line, rest, expected_pragma): - # type: (bytes, bytes, bytes, bytes) -> ExpectedContents +def _get_expected_contents( + first_line: bytes, + second_line: bytes, + rest: bytes, + expected_pragma: bytes, +) -> ExpectedContents: ending = b'\r\n' if first_line.endswith(b'\r\n') else b'\n' if first_line.startswith(b'#!'): @@ -60,7 +55,7 @@ def _get_expected_contents(first_line, second_line, rest, expected_pragma): rest = second_line + rest if potential_coding.rstrip(b'\r\n') == expected_pragma: - pragma_status = True # type: Optional[bool] + pragma_status: Optional[bool] = True elif has_coding(potential_coding): pragma_status = None else: @@ -72,8 +67,11 @@ def _get_expected_contents(first_line, second_line, rest, expected_pragma): ) -def fix_encoding_pragma(f, remove=False, expected_pragma=DEFAULT_PRAGMA): - # type: (IO[bytes], bool, bytes) -> int +def fix_encoding_pragma( + f: IO[bytes], + remove: bool = False, + expected_pragma: bytes = DEFAULT_PRAGMA, +) -> int: expected = _get_expected_contents( f.readline(), f.readline(), f.read(), expected_pragma, ) @@ -103,21 +101,20 @@ def fix_encoding_pragma(f, remove=False, expected_pragma=DEFAULT_PRAGMA): return 1 -def _normalize_pragma(pragma): # type: (Union[bytes, str]) -> bytes - if not isinstance(pragma, bytes): - pragma = pragma.encode('UTF-8') - return pragma.rstrip() +def _normalize_pragma(pragma: str) -> bytes: + return pragma.encode().rstrip() -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser( 'Fixes the encoding pragma of python files', ) parser.add_argument('filenames', nargs='*', help='Filenames to fix') parser.add_argument( '--pragma', default=DEFAULT_PRAGMA, type=_normalize_pragma, - help='The encoding pragma to use. Default: {}'.format( - DEFAULT_PRAGMA.decode(), + help=( + f'The encoding pragma to use. ' + f'Default: {DEFAULT_PRAGMA.decode()}' ), ) parser.add_argument( @@ -141,9 +138,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int retv |= file_ret if file_ret: print( - fmt.format( - pragma=args.pragma.decode(), filename=filename, - ), + fmt.format(pragma=args.pragma.decode(), filename=filename), ) return retv diff --git a/pre_commit_hooks/forbid_new_submodules.py b/pre_commit_hooks/forbid_new_submodules.py index bdbd6f7f..c144d728 100644 --- a/pre_commit_hooks/forbid_new_submodules.py +++ b/pre_commit_hooks/forbid_new_submodules.py @@ -1,14 +1,10 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - from typing import Optional from typing import Sequence from pre_commit_hooks.util import cmd_output -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: # `argv` is ignored, pre-commit will send us a list of files that we # don't care about added_diff = cmd_output( @@ -19,7 +15,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int metadata, filename = line.split('\t', 1) new_mode = metadata.split(' ')[1] if new_mode == '160000': - print('{}: new submodule introduced'.format(filename)) + print(f'{filename}: new submodule introduced') retv = 1 if retv: diff --git a/pre_commit_hooks/mixed_line_ending.py b/pre_commit_hooks/mixed_line_ending.py index 90aef035..0ef8e2c0 100644 --- a/pre_commit_hooks/mixed_line_ending.py +++ b/pre_commit_hooks/mixed_line_ending.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse import collections from typing import Dict @@ -17,7 +13,7 @@ FIX_TO_LINE_ENDING = {'cr': CR, 'crlf': CRLF, 'lf': LF} -def _fix(filename, contents, ending): # type: (str, bytes, bytes) -> None +def _fix(filename: str, contents: bytes, ending: bytes) -> None: new_contents = b''.join( line.rstrip(b'\r\n') + ending for line in contents.splitlines(True) ) @@ -25,11 +21,11 @@ def _fix(filename, contents, ending): # type: (str, bytes, bytes) -> None f.write(new_contents) -def fix_filename(filename, fix): # type: (str, str) -> int +def fix_filename(filename: str, fix: str) -> int: with open(filename, 'rb') as f: contents = f.read() - counts = collections.defaultdict(int) # type: Dict[bytes, int] + counts: Dict[bytes, int] = collections.defaultdict(int) for line in contents.splitlines(True): for ending in ALL_ENDINGS: @@ -66,7 +62,7 @@ def fix_filename(filename, fix): # type: (str, str) -> int return other_endings -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument( '-f', '--fix', @@ -81,9 +77,9 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for filename in args.filenames: if fix_filename(filename, args.fix): if args.fix == 'no': - print('{}: mixed line endings'.format(filename)) + print(f'{filename}: mixed line endings') else: - print('{}: fixed mixed line endings'.format(filename)) + print(f'{filename}: fixed mixed line endings') retv = 1 return retv diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index 31310595..fb1506f9 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import argparse import re from typing import AbstractSet @@ -10,8 +8,10 @@ from pre_commit_hooks.util import cmd_output -def is_on_branch(protected, patterns=frozenset()): - # type: (AbstractSet[str], AbstractSet[str]) -> bool +def is_on_branch( + protected: AbstractSet[str], + patterns: AbstractSet[str] = frozenset(), +) -> bool: try: ref_name = cmd_output('git', 'symbolic-ref', 'HEAD') except CalledProcessError: @@ -23,7 +23,7 @@ def is_on_branch(protected, patterns=frozenset()): ) -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = 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 7d515f47..25827dc4 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -1,10 +1,5 @@ -from __future__ import print_function - import argparse -import io import json -import sys -from collections import OrderedDict from difflib import unified_diff from typing import List from typing import Mapping @@ -13,38 +8,36 @@ from typing import Tuple from typing import Union -from six import text_type - def _get_pretty_format( - contents, indent, ensure_ascii=True, sort_keys=True, top_keys=(), -): # type: (str, str, bool, bool, Sequence[str]) -> str - def pairs_first(pairs): - # type: (Sequence[Tuple[str, str]]) -> Mapping[str, str] + contents: str, + indent: str, + ensure_ascii: bool = True, + sort_keys: bool = True, + top_keys: Sequence[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] if sort_keys: - after = sorted(after, key=lambda x: x[0]) - return OrderedDict(before + after) + after.sort() + return dict(before + after) json_pretty = json.dumps( json.loads(contents, object_pairs_hook=pairs_first), indent=indent, ensure_ascii=ensure_ascii, - # Workaround for https://bugs.python.org/issue16333 - separators=(',', ': '), ) - # Ensure unicode (Py2) and add the newline that dumps does not end with. - return text_type(json_pretty) + '\n' + return f'{json_pretty}\n' -def _autofix(filename, new_contents): # type: (str, str) -> None - print('Fixing file {}'.format(filename)) - with io.open(filename, 'w', encoding='UTF-8') as f: +def _autofix(filename: str, new_contents: str) -> None: + print(f'Fixing file {filename}') + with open(filename, 'w', encoding='UTF-8') as f: f.write(new_contents) -def parse_num_to_int(s): # type: (str) -> Union[int, str] +def parse_num_to_int(s: str) -> Union[int, str]: """Convert string numbers to int, leaving strings as is.""" try: return int(s) @@ -52,18 +45,18 @@ def parse_num_to_int(s): # type: (str) -> Union[int, str] return s -def parse_topkeys(s): # type: (str) -> List[str] +def parse_topkeys(s: str) -> List[str]: return s.split(',') -def get_diff(source, target, file): # type: (str, str, str) -> str +def get_diff(source: str, target: str, file: str) -> str: source_lines = source.splitlines(True) target_lines = target.splitlines(True) diff = unified_diff(source_lines, target_lines, fromfile=file, tofile=file) return ''.join(diff) -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument( '--autofix', @@ -110,7 +103,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int status = 0 for json_file in args.filenames: - with io.open(json_file, encoding='UTF-8') as f: + with open(json_file, encoding='UTF-8') as f: contents = f.read() try: @@ -131,8 +124,8 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int status = 1 except ValueError: print( - 'Input File {} is not a valid JSON, consider using check-json' - .format(json_file), + f'Input File {json_file} is not a valid JSON, consider using ' + f'check-json', ) return 1 @@ -140,4 +133,4 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 1aa0dffa..dc41815a 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import argparse from typing import IO from typing import List @@ -11,15 +9,13 @@ FAIL = 1 -class Requirement(object): - - def __init__(self): # type: () -> None - super(Requirement, self).__init__() - self.value = None # type: Optional[bytes] - self.comments = [] # type: List[bytes] +class Requirement: + def __init__(self) -> None: + self.value: Optional[bytes] = None + self.comments: List[bytes] = [] @property - def name(self): # type: () -> bytes + def name(self) -> bytes: assert self.value is not None, self.value for egg in (b'#egg=', b'&egg='): if egg in self.value: @@ -27,7 +23,7 @@ def name(self): # type: () -> bytes return self.value.lower().partition(b'==')[0] - def __lt__(self, requirement): # type: (Requirement) -> int + def __lt__(self, requirement: 'Requirement') -> int: # \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 @@ -39,10 +35,10 @@ def __lt__(self, requirement): # type: (Requirement) -> int return self.name < requirement.name -def fix_requirements(f): # type: (IO[bytes]) -> int - requirements = [] # type: List[Requirement] +def fix_requirements(f: IO[bytes]) -> int: + requirements: List[Requirement] = [] before = list(f) - after = [] # type: List[bytes] + after: List[bytes] = [] before_string = b''.join(before) @@ -109,7 +105,7 @@ def fix_requirements(f): # type: (IO[bytes]) -> int return FAIL -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -121,7 +117,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ret_for_file = fix_requirements(file_obj) if ret_for_file: - print('Sorting {}'.format(arg)) + print(f'Sorting {arg}') retv |= ret_for_file diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py index a381679f..8ebc84ff 100755 --- a/pre_commit_hooks/sort_simple_yaml.py +++ b/pre_commit_hooks/sort_simple_yaml.py @@ -18,8 +18,6 @@ In other words, we don't sort deeper than the top layer, and might corrupt complicated YAML files. """ -from __future__ import print_function - import argparse from typing import List from typing import Optional @@ -29,7 +27,7 @@ QUOTES = ["'", '"'] -def sort(lines): # type: (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) @@ -47,7 +45,7 @@ def sort(lines): # type: (List[str]) -> List[str] return new_lines -def parse_block(lines, header=False): # type: (List[str], bool) -> 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 @@ -63,7 +61,7 @@ def parse_block(lines, header=False): # type: (List[str], bool) -> List[str] return block_lines -def parse_blocks(lines): # type: (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 @@ -80,7 +78,7 @@ def parse_blocks(lines): # type: (List[str]) -> List[List[str]] return blocks -def first_key(lines): # type: (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 @@ -102,7 +100,7 @@ def first_key(lines): # type: (List[str]) -> str return '' # not actually reached in reality -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -115,7 +113,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int new_lines = sort(lines) if lines != new_lines: - print('Fixing file `{filename}`'.format(filename=filename)) + print(f'Fixing file `{filename}`') f.seek(0) f.write('\n'.join(new_lines) + '\n') f.truncate() diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py index 813ef64e..3fdb6e2f 100644 --- a/pre_commit_hooks/string_fixer.py +++ b/pre_commit_hooks/string_fixer.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import argparse import io import re @@ -13,7 +9,7 @@ START_QUOTE_RE = re.compile('^[a-zA-Z]*"') -def handle_match(token_text): # type: (str) -> str +def handle_match(token_text: str) -> str: if '"""' in token_text or "'''" in token_text: return token_text @@ -28,7 +24,7 @@ def handle_match(token_text): # type: (str) -> str return token_text -def get_line_offsets_by_line_no(src): # type: (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): @@ -36,8 +32,8 @@ def get_line_offsets_by_line_no(src): # type: (str) -> List[int] return offsets -def fix_strings(filename): # type: (str) -> int - with io.open(filename, encoding='UTF-8', newline='') as f: +def fix_strings(filename: str) -> int: + with open(filename, encoding='UTF-8', newline='') as f: contents = f.read() line_offsets = get_line_offsets_by_line_no(contents) @@ -57,14 +53,14 @@ def fix_strings(filename): # type: (str) -> int new_contents = ''.join(splitcontents) if contents != new_contents: - with io.open(filename, 'w', encoding='UTF-8', newline='') as f: + with open(filename, 'w', encoding='UTF-8', newline='') as f: f.write(new_contents) return 1 else: return 0 -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -74,7 +70,7 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for filename in args.filenames: return_value = fix_strings(filename) if return_value != 0: - print('Fixing strings in {}'.format(filename)) + print(f'Fixing strings in {filename}') retv |= return_value return retv diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py index d93595f0..b8cf9152 100644 --- a/pre_commit_hooks/tests_should_end_in_test.py +++ b/pre_commit_hooks/tests_should_end_in_test.py @@ -1,14 +1,11 @@ -from __future__ import print_function - import argparse import os.path import re -import sys from typing import Optional from typing import Sequence -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') parser.add_argument( @@ -27,14 +24,10 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int not base == 'conftest.py' ): retcode = 1 - print( - '{} does not match pattern "{}"'.format( - filename, test_name_pattern, - ), - ) + print(f'{filename} does not match pattern "{test_name_pattern}"') return retcode if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index a21b54fc..05ed9994 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -1,14 +1,14 @@ -from __future__ import print_function - import argparse import os -import sys from typing import Optional from typing import Sequence -def _fix_file(filename, is_markdown, chars): - # type: (str, bool, Optional[bytes]) -> bool +def _fix_file( + filename: str, + is_markdown: bool, + chars: Optional[bytes], +) -> bool: with open(filename, mode='rb') as file_processed: lines = file_processed.readlines() newlines = [_process_line(line, is_markdown, chars) for line in lines] @@ -21,8 +21,11 @@ def _fix_file(filename, is_markdown, chars): return False -def _process_line(line, is_markdown, chars): - # type: (bytes, bool, Optional[bytes]) -> bytes +def _process_line( + line: bytes, + is_markdown: bool, + chars: Optional[bytes], +) -> bytes: if line[-2:] == b'\r\n': eol = b'\r\n' line = line[:-2] @@ -37,7 +40,7 @@ def _process_line(line, is_markdown, chars): return line.rstrip(chars) + eol -def main(argv=None): # type: (Optional[Sequence[str]]) -> int +def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument( '--no-markdown-linebreak-ext', @@ -80,20 +83,20 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int for ext in md_exts: if any(c in ext[1:] for c in r'./\:'): parser.error( - 'bad --markdown-linebreak-ext extension {!r} (has . / \\ :)\n' - " (probably filename; use '--markdown-linebreak-ext=EXT')" - .format(ext), + f'bad --markdown-linebreak-ext extension ' + f'{ext!r} (has . / \\ :)\n' + f" (probably filename; use '--markdown-linebreak-ext=EXT')", ) - chars = None if args.chars is None else args.chars.encode('utf-8') + chars = None if args.chars is None else args.chars.encode() return_code = 0 for filename in args.filenames: _, extension = os.path.splitext(filename.lower()) md = all_markdown or extension in md_exts if _fix_file(filename, md, chars): - print('Fixing {}'.format(filename)) + print(f'Fixing {filename}') return_code = 1 return return_code if __name__ == '__main__': - sys.exit(main()) + exit(main()) diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py index 3b960e36..e04b0150 100644 --- a/pre_commit_hooks/util.py +++ b/pre_commit_hooks/util.py @@ -1,9 +1,6 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import subprocess from typing import Any +from typing import Optional from typing import Set @@ -11,18 +8,17 @@ class CalledProcessError(RuntimeError): pass -def added_files(): # type: () -> 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, **kwargs): # type: (*str, **Any) -> str - retcode = kwargs.pop('retcode', 0) +def cmd_output(*cmd: str, retcode: Optional[int] = 0, **kwargs: Any) -> str: kwargs.setdefault('stdout', subprocess.PIPE) kwargs.setdefault('stderr', subprocess.PIPE) proc = subprocess.Popen(cmd, **kwargs) stdout, stderr = proc.communicate() - stdout = stdout.decode('UTF-8') + stdout = stdout.decode() if retcode is not None and proc.returncode != retcode: raise CalledProcessError(cmd, retcode, proc.returncode, stdout, stderr) return stdout diff --git a/setup.cfg b/setup.cfg index 4b793f7f..6b1a34d0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,13 +11,11 @@ license = MIT license_file = LICENSE classifiers = License :: OSI Approved :: MIT License - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 - Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy @@ -27,9 +25,7 @@ install_requires = flake8 ruamel.yaml>=0.15 toml - six - typing; python_version<"3.5" -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +python_requires = >=3.6 [options.entry_points] console_scripts = diff --git a/testing/util.py b/testing/util.py index fac498c7..8e468d60 100644 --- a/testing/util.py +++ b/testing/util.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import os.path diff --git a/tests/autopep8_wrapper_test.py b/tests/autopep8_wrapper_test.py index 615ec25c..f8030b51 100644 --- a/tests/autopep8_wrapper_test.py +++ b/tests/autopep8_wrapper_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import pytest from pre_commit_hooks.autopep8_wrapper import main diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index 2f67d1b0..c33a9ca4 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import distutils.spawn import pytest @@ -78,7 +75,7 @@ def has_gitlfs(): @xfailif_no_gitlfs def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv(str('HOME'), str(temp_git_dir.strpath)) + monkeypatch.setenv('HOME', str(temp_git_dir.strpath)) cmd_output('git', 'lfs', 'install') temp_git_dir.join('f.py').write('a' * 10000) cmd_output('git', 'lfs', 'track', 'f.py') @@ -90,7 +87,7 @@ def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover @xfailif_no_gitlfs def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv(str('HOME'), str(temp_git_dir.strpath)) + monkeypatch.setenv('HOME', str(temp_git_dir.strpath)) cmd_output('git', 'lfs', 'install') cmd_output('git', 'lfs', 'track', 'a.bin', 'b.bin') # First add the file we're going to move diff --git a/tests/check_ast_test.py b/tests/check_ast_test.py index c16f5fcc..686fd116 100644 --- a/tests/check_ast_test.py +++ b/tests/check_ast_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - 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 8e18854f..01193e83 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -7,7 +7,7 @@ from pre_commit_hooks.check_builtin_literals import Visitor BUILTIN_CONSTRUCTORS = '''\ -from six.moves import builtins +import builtins c1 = complex() d1 = dict() diff --git a/tests/check_byte_order_marker_test.py b/tests/check_byte_order_marker_test.py index 53cb4a1b..9995200a 100644 --- a/tests/check_byte_order_marker_test.py +++ b/tests/check_byte_order_marker_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - 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 077b41b6..53de852e 100644 --- a/tests/check_case_conflict_test.py +++ b/tests/check_case_conflict_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - from pre_commit_hooks.check_case_conflict import find_conflicting_filenames from pre_commit_hooks.check_case_conflict import main from pre_commit_hooks.util import cmd_output diff --git a/tests/check_docstring_first_test.py b/tests/check_docstring_first_test.py index 0973a58f..7ad876ff 100644 --- a/tests/check_docstring_first_test.py +++ b/tests/check_docstring_first_test.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals - 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 0cb9dcfd..15f0c790 100644 --- a/tests/check_executables_have_shebangs_test.py +++ b/tests/check_executables_have_shebangs_test.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals - import pytest from pre_commit_hooks.check_executables_have_shebangs import main @@ -12,7 +8,7 @@ b'#!/bin/bash\nhello world\n', b'#!/usr/bin/env python3.6', b'#!python', - '#!☃'.encode('UTF-8'), + '#!☃'.encode(), ), ) def test_has_shebang(content, tmpdir): @@ -27,7 +23,7 @@ def test_has_shebang(content, tmpdir): b' #!python\n', b'\n#!python\n', b'python\n', - '☃'.encode('UTF-8'), + '☃'.encode(), ), ) @@ -36,4 +32,4 @@ def test_bad_shebang(content, tmpdir, capsys): path.write(content, 'wb') assert main((path.strpath,)) == 1 _, stderr = capsys.readouterr() - assert stderr.startswith('{}: marked executable but'.format(path.strpath)) + assert stderr.startswith(f'{path}: marked executable but') diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index af7cc43b..9968507b 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import os import shutil diff --git a/tests/check_toml_test.py b/tests/check_toml_test.py index 1172c40a..9f186d15 100644 --- a/tests/check_toml_test.py +++ b/tests/check_toml_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - 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 00e5396d..b893c98f 100644 --- a/tests/check_vcs_permalinks_test.py +++ b/tests/check_vcs_permalinks_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - from pre_commit_hooks.check_vcs_permalinks import main diff --git a/tests/check_yaml_test.py b/tests/check_yaml_test.py index d267150a..2f869d15 100644 --- a/tests/check_yaml_test.py +++ b/tests/check_yaml_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import pytest from pre_commit_hooks.check_yaml import main diff --git a/tests/conftest.py b/tests/conftest.py index da206cb9..f98ae349 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - 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 d15f5f7c..f2cabc1d 100644 --- a/tests/debug_statement_hook_test.py +++ b/tests/debug_statement_hook_test.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals - import ast from pre_commit_hooks.debug_statement_hook import Debug diff --git a/tests/fix_encoding_pragma_test.py b/tests/fix_encoding_pragma_test.py index d94b7256..f3531f26 100644 --- a/tests/fix_encoding_pragma_test.py +++ b/tests/fix_encoding_pragma_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import io import pytest @@ -129,9 +126,6 @@ def test_not_ok_input_alternate_pragma(): @pytest.mark.parametrize( ('input_s', 'expected'), ( - # Python 2 cli parameters are bytes - (b'# coding: utf-8', b'# coding: utf-8'), - # Python 3 cli parameters are text ('# coding: utf-8', b'# coding: utf-8'), # trailing whitespace ('# coding: utf-8\n', b'# coding: utf-8'), @@ -149,7 +143,7 @@ def test_integration_alternate_pragma(tmpdir, capsys): assert main((f.strpath, '--pragma', pragma)) == 1 assert f.read() == '# coding: utf-8\nx = 1\n' out, _ = capsys.readouterr() - assert out == 'Added `# coding: utf-8` to {}\n'.format(f.strpath) + assert out == f'Added `# coding: utf-8` to {f.strpath}\n' def test_crlf_ok(tmpdir): diff --git a/tests/forbid_new_submodules_test.py b/tests/forbid_new_submodules_test.py index 523628d6..76191820 100644 --- a/tests/forbid_new_submodules_test.py +++ b/tests/forbid_new_submodules_test.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import subprocess import pytest diff --git a/tests/mixed_line_ending_test.py b/tests/mixed_line_ending_test.py index 8ae93547..c438f745 100644 --- a/tests/mixed_line_ending_test.py +++ b/tests/mixed_line_ending_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import pytest from pre_commit_hooks.mixed_line_ending import main @@ -86,7 +83,7 @@ def test_no_fix_does_not_modify(tmpdir, capsys): assert ret == 1 assert path.read_binary() == contents out, _ = capsys.readouterr() - assert out == '{}: mixed line endings\n'.format(path) + assert out == f'{path}: mixed line endings\n' def test_fix_lf(tmpdir, capsys): @@ -97,7 +94,7 @@ def test_fix_lf(tmpdir, capsys): assert ret == 1 assert path.read_binary() == b'foo\nbar\nbaz\n' out, _ = capsys.readouterr() - assert out == '{}: fixed mixed line endings\n'.format(path) + assert out == f'{path}: fixed mixed line endings\n' def test_fix_crlf(tmpdir): diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py index a2ab1f1a..72b32e64 100644 --- a/tests/no_commit_to_branch_test.py +++ b/tests/no_commit_to_branch_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - 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 b42e504c..59a87f0e 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -2,7 +2,6 @@ import shutil import pytest -from six import PY2 from pre_commit_hooks.pretty_format_json import main from pre_commit_hooks.pretty_format_json import parse_num_to_int @@ -42,7 +41,6 @@ def test_unsorted_main(filename, expected_retval): assert ret == expected_retval -@pytest.mark.skipif(PY2, reason='Requires Python3') @pytest.mark.parametrize( ('filename', 'expected_retval'), ( ('not_pretty_formatted_json.json', 1), @@ -52,7 +50,7 @@ def test_unsorted_main(filename, expected_retval): ('tab_pretty_formatted_json.json', 0), ), ) -def test_tab_main(filename, expected_retval): # pragma: no cover +def test_tab_main(filename, expected_retval): ret = main(['--indent', '\t', get_resource_path(filename)]) assert ret == expected_retval @@ -113,9 +111,9 @@ def test_diffing_output(capsys): expected_retval = 1 a = os.path.join('a', resource_path) b = os.path.join('b', resource_path) - expected_out = '''\ ---- {} -+++ {} + expected_out = f'''\ +--- {a} ++++ {b} @@ -1,6 +1,9 @@ {{ - "foo": @@ -130,7 +128,7 @@ def test_diffing_output(capsys): + "blah": null, + "foo": "bar" }} -'''.format(a, b) +''' actual_retval = main([resource_path]) actual_out, actual_err = capsys.readouterr() diff --git a/tests/readme_test.py b/tests/readme_test.py index fd6d2654..7df7fcfe 100644 --- a/tests/readme_test.py +++ b/tests/readme_test.py @@ -1,15 +1,10 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - -import io - from pre_commit_hooks.check_yaml import yaml def test_readme_contains_all_hooks(): - with io.open('README.md', encoding='UTF-8') as f: + with open('README.md', encoding='UTF-8') as f: readme_contents = f.read() - with io.open('.pre-commit-hooks.yaml', encoding='UTF-8') as f: + with open('.pre-commit-hooks.yaml', encoding='UTF-8') as f: hooks = yaml.load(f) for hook in hooks: - assert '`{}`'.format(hook['id']) in readme_contents + assert f'`{hook["id"]}`' in readme_contents diff --git a/tests/sort_simple_yaml_test.py b/tests/sort_simple_yaml_test.py index 4261d5d4..69ad388e 100644 --- a/tests/sort_simple_yaml_test.py +++ b/tests/sort_simple_yaml_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import os import pytest diff --git a/tests/string_fixer_test.py b/tests/string_fixer_test.py index 4adca4a5..77a51cf0 100644 --- a/tests/string_fixer_test.py +++ b/tests/string_fixer_test.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals - import textwrap import pytest diff --git a/tests/trailing_whitespace_fixer_test.py b/tests/trailing_whitespace_fixer_test.py index 97f9aefe..53177ac9 100644 --- a/tests/trailing_whitespace_fixer_test.py +++ b/tests/trailing_whitespace_fixer_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import pytest from pre_commit_hooks.trailing_whitespace_fixer import main @@ -46,7 +43,7 @@ def test_fixes_markdown_files(tmpdir, ext): '\t\n' # trailing tabs are stripped anyway '\n ', # whitespace at the end of the file is removed ) - ret = main((path.strpath, '--markdown-linebreak-ext={}'.format(ext))) + ret = main((path.strpath, f'--markdown-linebreak-ext={ext}')) assert ret == 1 assert path.read() == ( 'foo \n' diff --git a/tests/util_test.py b/tests/util_test.py index 9b2d7236..b42ee6f9 100644 --- a/tests/util_test.py +++ b/tests/util_test.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals - import pytest from pre_commit_hooks.util import CalledProcessError diff --git a/tox.ini b/tox.ini index a6b3fb4d..cb58fee6 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py36,py37,pypy,pypy3,pre-commit +envlist = py36,py37,py38,pypy3,pre-commit [testenv] deps = -rrequirements-dev.txt From ace459bec57bbcb88c4fe9d00c603467fb3f572b Mon Sep 17 00:00:00 2001 From: Alexander Demin Date: Wed, 12 Feb 2020 21:54:05 +0000 Subject: [PATCH 087/334] Skip empty variables in detect_aws_credentials --- pre_commit_hooks/detect_aws_credentials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index fe18f4df..aae0734c 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -84,7 +84,7 @@ def check_file_for_aws_keys( for key in keys: # naively match the entire file, low chance of incorrect # collision - if key in text_body: + if key and key in text_body: bad_files.append(BadFile(filename, key[:4].ljust(28, '*'))) return bad_files From 75d4832e98e25d67530505a319f33ebc278def70 Mon Sep 17 00:00:00 2001 From: Alexander Demin Date: Thu, 13 Feb 2020 12:01:38 +0000 Subject: [PATCH 088/334] Unit test for empty AWS variables --- pre_commit_hooks/detect_aws_credentials.py | 4 ++-- tests/detect_aws_credentials_test.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index aae0734c..9ef8fec1 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -31,7 +31,7 @@ def get_aws_secrets_from_env() -> Set[str]: for env_var in ( 'AWS_SECRET_ACCESS_KEY', 'AWS_SECURITY_TOKEN', 'AWS_SESSION_TOKEN', ): - if env_var in os.environ: + if env_var in os.environ and os.environ[env_var]: keys.add(os.environ[env_var]) return keys @@ -84,7 +84,7 @@ def check_file_for_aws_keys( for key in keys: # naively match the entire file, low chance of incorrect # collision - if key and key in text_body: + if key in text_body: bad_files.append(BadFile(filename, key[:4].ljust(28, '*'))) return bad_files diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py index 777fb480..46e5b364 100644 --- a/tests/detect_aws_credentials_test.py +++ b/tests/detect_aws_credentials_test.py @@ -47,6 +47,8 @@ def test_get_aws_credentials_file_from_env(env_vars, values): ({'AWS_SECRET_ACCESS_KEY': 'foo'}, {'foo'}), ({'AWS_SECURITY_TOKEN': 'foo'}, {'foo'}), ({'AWS_SESSION_TOKEN': 'foo'}, {'foo'}), + ({'AWS_SESSION_TOKEN': ''}, set()), + ({'AWS_SESSION_TOKEN': 'foo', 'AWS_SECURITY_TOKEN': ''}, {'foo'}), ({'AWS_DUMMY_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'}, {'bar'}), ( {'AWS_SECRET_ACCESS_KEY': 'foo', 'AWS_SECURITY_TOKEN': 'bar'}, From b3a28deca775e09a578f0200e6af998c0d8a126e Mon Sep 17 00:00:00 2001 From: Alexander Demin Date: Thu, 13 Feb 2020 17:12:45 +0000 Subject: [PATCH 089/334] Review fixes --- pre_commit_hooks/detect_aws_credentials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index 9ef8fec1..a744b6f9 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -31,7 +31,7 @@ def get_aws_secrets_from_env() -> Set[str]: for env_var in ( 'AWS_SECRET_ACCESS_KEY', 'AWS_SECURITY_TOKEN', 'AWS_SESSION_TOKEN', ): - if env_var in os.environ and os.environ[env_var]: + if os.environ.get(env_var): keys.add(os.environ[env_var]) return keys From 43bfa05e8946f394e6967c63cad8875685d4c6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Kosi=C5=84ski?= Date: Tue, 18 Feb 2020 19:10:23 +0100 Subject: [PATCH 090/334] added wdb to DEBUG_STATEMENTS set --- pre_commit_hooks/debug_statement_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 00423ac8..6d2dc827 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -7,7 +7,7 @@ from typing import Sequence -DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb', 'rpdb'} +DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb', 'rpdb', 'wdb'} class Debug(NamedTuple): From 21553c2ca913fefe2eaffea8778035e108a671c3 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 18 Feb 2020 10:24:17 -0800 Subject: [PATCH 091/334] Allow arbitrarily encoded files to be checked with detect-aws-credentials --- pre_commit_hooks/detect_aws_credentials.py | 10 ++++++---- tests/detect_aws_credentials_test.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index a744b6f9..1663cfd6 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -69,7 +69,7 @@ def get_aws_secrets_from_file(credentials_file: str) -> Set[str]: def check_file_for_aws_keys( filenames: Sequence[str], - keys: Set[str], + keys: Set[bytes], ) -> List[BadFile]: """Check if files contain AWS secrets. @@ -79,13 +79,14 @@ def check_file_for_aws_keys( bad_files = [] for filename in filenames: - with open(filename, 'r') as content: + with open(filename, 'rb') as content: text_body = content.read() for key in keys: # naively match the entire file, low chance of incorrect # collision if key in text_body: - bad_files.append(BadFile(filename, key[:4].ljust(28, '*'))) + key_hidden = key.decode()[:4].ljust(28, '*') + bad_files.append(BadFile(filename, key_hidden)) return bad_files @@ -137,7 +138,8 @@ def main(argv: Optional[Sequence[str]] = None) -> int: ) return 2 - bad_filenames = check_file_for_aws_keys(args.filenames, keys) + keys_b = {key.encode() for key in keys} + bad_filenames = check_file_for_aws_keys(args.filenames, keys_b) if bad_filenames: for bad_file in bad_filenames: print(f'AWS secret found in {bad_file.filename}: {bad_file.key}') diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py index 46e5b364..41b7b0ae 100644 --- a/tests/detect_aws_credentials_test.py +++ b/tests/detect_aws_credentials_test.py @@ -117,6 +117,19 @@ def test_detect_aws_credentials(filename, expected_retval): assert ret == expected_retval +def test_allows_arbitrarily_encoded_files(tmpdir): + src_ini = tmpdir.join('src.ini') + src_ini.write( + '[default]\n' + 'aws_access_key_id=AKIASDFASDF\n' + 'aws_secret_Access_key=9018asdf23908190238123\n', + ) + arbitrary_encoding = tmpdir.join('f') + arbitrary_encoding.write_binary(b'\x12\x9a\xe2\xf2') + ret = main((str(arbitrary_encoding), '--credentials-file', str(src_ini))) + assert ret == 0 + + @patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file') @patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env') def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys): From 165a5089655b7795ed446562d1401fc5f2f55eac Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 18 Feb 2020 10:30:47 -0800 Subject: [PATCH 092/334] Extend deprecation message to description This will make it show up on https://pre-commit.com/hooks.html --- .pre-commit-hooks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 666a2452..cef47c82 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -139,7 +139,7 @@ types: [python] - id: flake8 name: Flake8 (deprecated, use gitlab.com/pycqa/flake8) - description: This hook runs flake8. + description: This hook runs flake8. (deprecated, use gitlab.com/pycqa/flake8) entry: flake8 language: python types: [python] From 261fb3d66c68a832477996b9dc71bee2faac67fa Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 24 Feb 2020 10:57:26 -0800 Subject: [PATCH 093/334] pre-commit-hooks: python3.6.1+ --- .pre-commit-config.yaml | 5 +++-- setup.cfg | 2 +- tests/sort_simple_yaml_test.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 464609be..f3aff06d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,12 +16,13 @@ repos: rev: 3.7.9 hooks: - id: flake8 + additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 rev: v1.5 hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v2.0.1 + rev: v2.1.1 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports @@ -30,7 +31,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v1.26.2 + rev: v2.0.1 hooks: - id: pyupgrade args: [--py36-plus] diff --git a/setup.cfg b/setup.cfg index 6b1a34d0..c05ca0c7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,7 @@ install_requires = flake8 ruamel.yaml>=0.15 toml -python_requires = >=3.6 +python_requires = >=3.6.1 [options.entry_points] console_scripts = diff --git a/tests/sort_simple_yaml_test.py b/tests/sort_simple_yaml_test.py index 69ad388e..77e95d50 100644 --- a/tests/sort_simple_yaml_test.py +++ b/tests/sort_simple_yaml_test.py @@ -46,7 +46,7 @@ def test_integration_good_bad_lines(tmpdir, bad_lines, good_lines, retval): assert main([file_path]) == retval - with open(file_path, 'r') as f: + with open(file_path) as f: assert [line.rstrip() for line in f.readlines()] == good_lines From 1091574d2de1e522bc4c63c83113ecd61b858e9c Mon Sep 17 00:00:00 2001 From: Douglas Thor Date: Thu, 27 Feb 2020 15:04:33 -0800 Subject: [PATCH 094/334] Fix docs for pretty-format-json: default indent is **2** spaces. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c98ba1b8..b96f44f5 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Checks that all your JSON files are pretty. "Pretty" here means that keys are sorted and indented. You can configure this with the following commandline options: - `--autofix` - automatically format json files - - `--indent ...` - Control the indentation (either a number for a number of spaces or a string of whitespace). Defaults to 4 spaces. + - `--indent ...` - Control the indentation (either a number for a number of spaces or a string of whitespace). Defaults to 2 spaces. - `--no-ensure-ascii` preserve unicode characters instead of converting to escape sequences - `--no-sort-keys` - when autofixing, retain the original key ordering (instead of sorting the keys) - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. From a7f73434a6fa95b2f14c476e8a1d3d10590946d5 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 29 Feb 2020 20:34:45 -0800 Subject: [PATCH 095/334] Use covdefaults to handle coveragerc --- .coveragerc | 29 ---------------------------- requirements-dev.txt | 4 +--- setup.cfg | 3 +++ tests/detect_aws_credentials_test.py | 3 ++- 4 files changed, 6 insertions(+), 33 deletions(-) delete mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 7c592a95..00000000 --- a/.coveragerc +++ /dev/null @@ -1,29 +0,0 @@ -[run] -branch = True -source = - . -omit = - .tox/* - /usr/* - setup.py - -[report] -show_missing = True -skip_covered = True -exclude_lines = - # Have to re-enable the standard pragma - \#\s*pragma: no cover - - # Don't complain if tests don't hit defensive assertion code: - ^\s*raise AssertionError\b - ^\s*raise NotImplementedError\b - ^\s*return NotImplemented\b - ^\s*raise$ - - # Don't complain if non-runnable code isn't run: - ^if __name__ == ['"]__main__['"]:$ - -[html] -directory = coverage-html - -# vim:ft=dosini diff --git a/requirements-dev.txt b/requirements-dev.txt index cf74d9f5..67f6485d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,4 @@ --e . - +covdefaults coverage -mock pre-commit pytest diff --git a/setup.cfg b/setup.cfg index c05ca0c7..e6c488a1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -68,6 +68,9 @@ exclude = [bdist_wheel] universal = True +[coverage:run] +plugins = covdefaults + [mypy] check_untyped_defs = true disallow_any_generics = true diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py index 41b7b0ae..4f00744e 100644 --- a/tests/detect_aws_credentials_test.py +++ b/tests/detect_aws_credentials_test.py @@ -1,5 +1,6 @@ +from unittest.mock import patch + import pytest -from mock import patch from pre_commit_hooks.detect_aws_credentials import get_aws_cred_files_from_env from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env From 74024a9cfabfac28b7fdc80bd2540346a90f084f Mon Sep 17 00:00:00 2001 From: Daiki Katsuragawa <50144563+daikikatsuragawa@users.noreply.github.com> Date: Tue, 24 Mar 2020 02:30:14 +0900 Subject: [PATCH 096/334] Fix yaml formatting in README.md --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b96f44f5..ca4eef77 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,13 @@ See also: https://github.com/pre-commit/pre-commit Add this to your `.pre-commit-config.yaml` - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.5.0 # Use the ref you want to point at - hooks: - - id: trailing-whitespace - # - id: ... - +```yaml +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.5.0 # Use the ref you want to point at + hooks: + - id: trailing-whitespace + # - id: ... +``` ### Hooks available From bbcd31e00074aeab5cc15abaa2609ae38b8c398d Mon Sep 17 00:00:00 2001 From: Aniket Bhatnagar Date: Thu, 7 May 2020 21:02:12 +0100 Subject: [PATCH 097/334] Handled multiline dependencies --- pre_commit_hooks/requirements_txt_fixer.py | 16 ++++++++++++++-- tests/requirements_txt_fixer_test.py | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index dc41815a..61906927 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -34,6 +34,18 @@ def __lt__(self, requirement: 'Requirement') -> int: else: return self.name < requirement.name + def is_complete(self) -> bool: + return ( + self.value is not None and + not self.value.rstrip(b'\r\n').endswith(b'\\') + ) + + def append_value(self, value: bytes) -> None: + if self.value is not None: + self.value += value + else: + self.value = value + def fix_requirements(f: IO[bytes]) -> int: requirements: List[Requirement] = [] @@ -55,7 +67,7 @@ def fix_requirements(f: IO[bytes]) -> int: # If the most recent requirement object has a value, then it's # time to start building the next requirement object. - if not len(requirements) or requirements[-1].value is not None: + if not len(requirements) or requirements[-1].is_complete(): requirements.append(Requirement()) requirement = requirements[-1] @@ -73,7 +85,7 @@ def fix_requirements(f: IO[bytes]) -> int: elif line.startswith(b'#') or line.strip() == b'': requirement.comments.append(line) else: - requirement.value = line + requirement.append_value(line) # if a file ends in a comment, preserve it at the end if requirements[-1].value is None: diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index 7b9b07d9..17a9a41c 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -50,6 +50,24 @@ FAIL, b'Django\nijk\ngit+ssh://git_url@tag#egg=ocflib\n', ), + ( + b'b==1.0.0\n' + b'c=2.0.0 \\\n' + b' --hash=sha256:abcd\n' + b'a=3.0.0 \\\n' + b' --hash=sha256:a1b1c1d1', + FAIL, + b'a=3.0.0 \\\n' + b' --hash=sha256:a1b1c1d1\n' + b'b==1.0.0\n' + b'c=2.0.0 \\\n' + b' --hash=sha256:abcd\n', + ), + ( + b'a=2.0.0 \\\n --hash=sha256:abcd\nb==1.0.0\n', + PASS, + b'a=2.0.0 \\\n --hash=sha256:abcd\nb==1.0.0\n', + ), ), ) def test_integration(input_s, expected_retval, output, tmpdir): From 0872a71e1ecb6fbae2eea22355144a9aebdee797 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 11 May 2020 14:15:41 -0700 Subject: [PATCH 098/334] Run pre-commit autoupdate Committed via https://github.com/asottile/all-repos --- .pre-commit-config.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f3aff06d..4495eef2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,38 +13,38 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://gitlab.com/pycqa/flake8 - rev: 3.7.9 + rev: 3.8.0 hooks: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.5 + rev: v1.5.2 hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v2.1.1 + rev: v2.4.0 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports - rev: v1.9.0 + rev: v2.3.0 hooks: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.0.1 + rev: v2.4.1 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/asottile/add-trailing-comma - rev: v1.5.0 + rev: v2.0.1 hooks: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.6.0 + rev: v1.9.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.761 + rev: v0.770 hooks: - id: mypy From b9cc9d7761af788363515a49bf2a47f22c309975 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 14 May 2020 16:00:29 -0700 Subject: [PATCH 099/334] remove flake8 and suggest pycqa/flake8 --- .pre-commit-hooks.yaml | 17 +++++++++-------- pre_commit_hooks/autopep8_wrapper.py | 9 --------- pre_commit_hooks/removed.py | 15 +++++++++++++++ setup.cfg | 2 +- tests/autopep8_wrapper_test.py | 10 ---------- tests/removed_test.py | 16 ++++++++++++++++ 6 files changed, 41 insertions(+), 28 deletions(-) delete mode 100644 pre_commit_hooks/autopep8_wrapper.py create mode 100644 pre_commit_hooks/removed.py delete mode 100644 tests/autopep8_wrapper_test.py create mode 100644 tests/removed_test.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index cef47c82..d8cea9ba 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,10 +1,10 @@ - id: autopep8-wrapper name: autopep8 wrapper description: This is deprecated, use pre-commit/mirrors-autopep8 instead. - entry: autopep8-wrapper + entry: pre-commit-hooks-removed autopep8-wrapper autopep8 https://github.com/pre-commit/mirrors-autopep8 language: python - types: [python] - args: [-i] + always_run: true + pass_filenames: false - id: check-added-large-files name: Check for added large files description: Prevent giant files from being committed @@ -140,10 +140,10 @@ - id: flake8 name: Flake8 (deprecated, use gitlab.com/pycqa/flake8) description: This hook runs flake8. (deprecated, use gitlab.com/pycqa/flake8) - entry: flake8 + entry: pre-commit-hooks-removed flake8 flake8 https://gitlab.com/pycqa/flake8 language: python - types: [python] - require_serial: true + always_run: true + pass_filenames: false - id: forbid-new-submodules name: Forbid new submodules language: python @@ -170,9 +170,10 @@ - id: pyflakes name: Pyflakes (DEPRECATED, use flake8) description: This hook runs pyflakes. (This is deprecated, use flake8). - entry: pyflakes + entry: pre-commit-hooks-removed pyflakes flake8 https://gitlab.com/pycqa/flake8 language: python - types: [python] + always_run: true + pass_filenames: false - id: requirements-txt-fixer name: Fix requirements.txt description: Sorts entries in requirements.txt diff --git a/pre_commit_hooks/autopep8_wrapper.py b/pre_commit_hooks/autopep8_wrapper.py deleted file mode 100644 index 78a1cce8..00000000 --- a/pre_commit_hooks/autopep8_wrapper.py +++ /dev/null @@ -1,9 +0,0 @@ -def main() -> int: - raise SystemExit( - 'autopep8-wrapper is deprecated. Instead use autopep8 directly via ' - 'https://github.com/pre-commit/mirrors-autopep8', - ) - - -if __name__ == '__main__': - exit(main()) diff --git a/pre_commit_hooks/removed.py b/pre_commit_hooks/removed.py new file mode 100644 index 00000000..9710b2d6 --- /dev/null +++ b/pre_commit_hooks/removed.py @@ -0,0 +1,15 @@ +import sys +from typing import Optional +from typing import Sequence + + +def main(argv: Optional[Sequence[str]] = None) -> int: + argv = argv if argv is not None else sys.argv[1:] + hookid, new_hookid, url = argv + raise SystemExit( + f'`{hookid}` has been removed -- use `{new_hookid}` from {url}', + ) + + +if __name__ == '__main__': + exit(main()) diff --git a/setup.cfg b/setup.cfg index e6c488a1..41138f48 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,6 @@ python_requires = >=3.6.1 [options.entry_points] console_scripts = - autopep8-wrapper = pre_commit_hooks.autopep8_wrapper:main check-added-large-files = pre_commit_hooks.check_added_large_files:main check-ast = pre_commit_hooks.check_ast:main check-builtin-literals = pre_commit_hooks.check_builtin_literals:main @@ -55,6 +54,7 @@ console_scripts = mixed-line-ending = pre_commit_hooks.mixed_line_ending:main name-tests-test = pre_commit_hooks.tests_should_end_in_test:main no-commit-to-branch = pre_commit_hooks.no_commit_to_branch:main + pre-commit-hooks-removed = pre_commit_hooks.removed:main pretty-format-json = pre_commit_hooks.pretty_format_json:main requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main diff --git a/tests/autopep8_wrapper_test.py b/tests/autopep8_wrapper_test.py deleted file mode 100644 index f8030b51..00000000 --- a/tests/autopep8_wrapper_test.py +++ /dev/null @@ -1,10 +0,0 @@ -import pytest - -from pre_commit_hooks.autopep8_wrapper import main - - -def test_invariantly_fails(): - with pytest.raises(SystemExit) as excinfo: - main() - msg, = excinfo.value.args - assert 'https://github.com/pre-commit/mirrors-autopep8' in msg diff --git a/tests/removed_test.py b/tests/removed_test.py new file mode 100644 index 00000000..83df1647 --- /dev/null +++ b/tests/removed_test.py @@ -0,0 +1,16 @@ +import pytest + +from pre_commit_hooks.removed import main + + +def test_always_fails(): + with pytest.raises(SystemExit) as excinfo: + main(( + 'autopep8-wrapper', 'autopep8', + 'https://github.com/pre-commit/mirrors-autopep8', + )) + msg, = excinfo.value.args + assert msg == ( + '`autopep8-wrapper` has been removed -- ' + 'use `autopep8` from https://github.com/pre-commit/mirrors-autopep8' + ) From e6d9355bf168c26b5ed6c8b7120cecf2bfe2f5b4 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 14 May 2020 16:16:09 -0700 Subject: [PATCH 100/334] Remove additional remnants of flake8 --- .pre-commit-hooks.yaml | 12 ++++++------ setup.cfg | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index d8cea9ba..3e4dc9ea 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,6 +1,6 @@ - id: autopep8-wrapper - name: autopep8 wrapper - description: This is deprecated, use pre-commit/mirrors-autopep8 instead. + name: autopep8 wrapper (removed) + description: (removed) use pre-commit/mirrors-autopep8 instead. entry: pre-commit-hooks-removed autopep8-wrapper autopep8 https://github.com/pre-commit/mirrors-autopep8 language: python always_run: true @@ -138,8 +138,8 @@ description: 'Add # -*- coding: utf-8 -*- to the top of python files' types: [python] - id: flake8 - name: Flake8 (deprecated, use gitlab.com/pycqa/flake8) - description: This hook runs flake8. (deprecated, use gitlab.com/pycqa/flake8) + name: Flake8 (removed) + description: (removed) use gitlab.com/pycqa/flake8 instead. entry: pre-commit-hooks-removed flake8 flake8 https://gitlab.com/pycqa/flake8 language: python always_run: true @@ -168,8 +168,8 @@ pass_filenames: false always_run: true - id: pyflakes - name: Pyflakes (DEPRECATED, use flake8) - description: This hook runs pyflakes. (This is deprecated, use flake8). + name: Pyflakes (removed) + description: (removed) use gitlab.com/pycqa/flake8 instead. entry: pre-commit-hooks-removed pyflakes flake8 https://gitlab.com/pycqa/flake8 language: python always_run: true diff --git a/setup.cfg b/setup.cfg index 41138f48..b42fd717 100644 --- a/setup.cfg +++ b/setup.cfg @@ -22,7 +22,6 @@ classifiers = [options] packages = find: install_requires = - flake8 ruamel.yaml>=0.15 toml python_requires = >=3.6.1 From 66250ba9bf5ae48f660b7648d9feca8ed0b18e58 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 14 May 2020 16:24:40 -0700 Subject: [PATCH 101/334] v3.0.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4495eef2..f44bbeb1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.5.0 + rev: v3.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 24464936..209c03b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,43 @@ +3.0.0 - 2020-05-14 +================== + +### Features +- `detect-aws-credentials`: skip empty aws keys + - #450 PR by @begoon. + - #449 issue by @begoon. +- `debug-statements`: add detection `wdb` debugger + - #452 PR by @itsdkey. + - #451 issue by @itsdkey. +- `requirements-txt-fixer`: support line continuation for dependencies + - #469 PR by @aniketbhatnagar. + - #465 issue by @aniketbhatnagar. + +### Fixes +- `detect-aws-credentials`: fix `UnicodeDecodeError` when running on non-UTF8 + files. + - #453 PR by @asottile. + - #393 PR by @a7p + - #346 issue by @rpdelaney. + +### Updating +- pre-commit/pre-commit-hooks now requires python3.6.1+ + - #447 PR by @asottile. + - #455 PR by @asottile. +- `flake8` / `pyflakes` have been removed, use `flake8` from `pycqa/flake8` + instead: + + ```yaml + - repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.1 + hooks: + - id: flake8 + ``` + + - #476 PR by @asottile. + - #477 PR by @asottile. + - #344 issue by @asottile. + + 2.5.0 - 2020-02-04 ================== diff --git a/README.md b/README.md index ca4eef77..ee7036dd 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.5.0 # Use the ref you want to point at + rev: v3.0.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index b42fd717..cae1b3b2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 2.5.0 +version = 3.0.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From c11c5483d69995bb8ae462b75f5532ce6ae02a77 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 14 May 2020 16:29:55 -0700 Subject: [PATCH 102/334] check-json: resolve TODO --- pre_commit_hooks/check_json.py | 3 +-- tests/check_json_test.py | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py index 25dbfd95..6026270c 100644 --- a/pre_commit_hooks/check_json.py +++ b/pre_commit_hooks/check_json.py @@ -14,8 +14,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: with open(filename, 'rb') as f: try: json.load(f) - # TODO: need UnicodeDecodeError? - except (ValueError, UnicodeDecodeError) as exc: + except ValueError as exc: print(f'{filename}: Failed to json decode ({exc})') retval = 1 return retval diff --git a/tests/check_json_test.py b/tests/check_json_test.py index 6654ed10..c63dc4c8 100644 --- a/tests/check_json_test.py +++ b/tests/check_json_test.py @@ -17,3 +17,9 @@ def test_main(capsys, filename, expected_retval): if expected_retval == 1: stdout, _ = capsys.readouterr() assert filename in stdout + + +def test_non_utf8_file(tmpdir): + f = tmpdir.join('t.json') + f.write_binary(b'\xa9\xfe\x12') + assert main((str(f),)) From 8febacdfedd236b70d2646d7c1e266b407dd25f7 Mon Sep 17 00:00:00 2001 From: Max Rozentsveyg Date: Sat, 16 May 2020 20:49:10 -0400 Subject: [PATCH 103/334] Support checking unicode TOML --- pre_commit_hooks/check_toml.py | 3 +-- tests/check_toml_test.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py index 51a1f15e..87496753 100644 --- a/pre_commit_hooks/check_toml.py +++ b/pre_commit_hooks/check_toml.py @@ -13,8 +13,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: retval = 0 for filename in args.filenames: try: - with open(filename) as f: - toml.load(f) + toml.load(filename) except toml.TomlDecodeError as exc: print(f'{filename}: {exc}') retval = 1 diff --git a/tests/check_toml_test.py b/tests/check_toml_test.py index 9f186d15..32837176 100644 --- a/tests/check_toml_test.py +++ b/tests/check_toml_test.py @@ -1,7 +1,7 @@ from pre_commit_hooks.check_toml import main -def test_toml_good(tmpdir): +def test_toml_bad(tmpdir): filename = tmpdir.join('f') filename.write(""" key = # INVALID @@ -12,7 +12,7 @@ def test_toml_good(tmpdir): assert ret == 1 -def test_toml_bad(tmpdir): +def test_toml_good(tmpdir): filename = tmpdir.join('f') filename.write( """ @@ -27,3 +27,10 @@ def test_toml_bad(tmpdir): ) ret = main((filename.strpath,)) assert ret == 0 + + +def test_toml_good_unicode(tmpdir): + filename = tmpdir.join('f') + filename.write_binary('letter = "\N{SNOWMAN}"\n'.encode()) + ret = main((filename.strpath,)) + assert ret == 0 From 0e2c0f75028c039052b637c17173833aaf5be97a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 16 May 2020 18:08:51 -0700 Subject: [PATCH 104/334] v3.0.1 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f44bbeb1..c5ccc795 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.0.0 + rev: v3.0.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 209c03b6..14230f26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +3.0.1 - 2020-05-16 +================== + +### Fixes +- `check-toml`: use UTF-8 encoding to load toml files + - #479 PR by @mxr. + - #474 issue by @staticdev. + 3.0.0 - 2020-05-14 ================== diff --git a/README.md b/README.md index ee7036dd..54db3a99 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.0.0 # Use the ref you want to point at + rev: v3.0.1 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index cae1b3b2..cf046894 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 3.0.0 +version = 3.0.1 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From c03ac576a3b5e1e9a4a0c54c2ffd78626db738ea Mon Sep 17 00:00:00 2001 From: Max Rozentsveyg Date: Sat, 16 May 2020 22:21:03 -0400 Subject: [PATCH 105/334] Remove `type: ignore` --- pre_commit_hooks/check_xml.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py index eddfdf99..59b4d59e 100644 --- a/pre_commit_hooks/check_xml.py +++ b/pre_commit_hooks/check_xml.py @@ -14,8 +14,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: for filename in args.filenames: try: with open(filename, 'rb') as xml_file: - # https://github.com/python/typeshed/pull/3725 - xml.sax.parse(xml_file, handler) # type: ignore + xml.sax.parse(xml_file, handler) except xml.sax.SAXException as exc: print(f'{filename}: Failed to xml parse ({exc})') retval = 1 From 7ebd420417572fa67221773be12c22b8e1dd3dc1 Mon Sep 17 00:00:00 2001 From: Max Rozentsveyg Date: Sat, 16 May 2020 23:58:27 -0400 Subject: [PATCH 106/334] Parse more operators in requirements --- pre_commit_hooks/requirements_txt_fixer.py | 17 +++++++++++++-- tests/requirements_txt_fixer_test.py | 25 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 61906927..78103a14 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -1,4 +1,5 @@ import argparse +import re from typing import IO from typing import List from typing import Optional @@ -10,6 +11,9 @@ class Requirement: + UNTIL_COMPARISON = re.compile(b'={2,3}|!=|~=|>=?|<=?') + UNTIL_SEP = re.compile(rb'[^;\s]+') + def __init__(self) -> None: self.value: Optional[bytes] = None self.comments: List[bytes] = [] @@ -17,11 +21,20 @@ def __init__(self) -> None: @property def name(self) -> bytes: assert self.value is not None, self.value + name = self.value.lower() for egg in (b'#egg=', b'&egg='): if egg in self.value: - return self.value.lower().partition(egg)[-1] + return name.partition(egg)[-1] + + m = self.UNTIL_SEP.match(name) + assert m is not None + + name = m.group() + m = self.UNTIL_COMPARISON.search(name) + if not m: + return name - return self.value.lower().partition(b'==')[0] + return name[:m.start()] def __lt__(self, requirement: 'Requirement') -> int: # \n means top of file comment, so always return True, diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index 17a9a41c..fae5a723 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -33,9 +33,28 @@ (b'\nfoo\nbar\n', FAIL, b'bar\n\nfoo\n'), (b'\nbar\nfoo\n', PASS, b'\nbar\nfoo\n'), ( - b'pyramid==1\npyramid-foo==2\n', - PASS, - b'pyramid==1\npyramid-foo==2\n', + b'pyramid-foo==1\npyramid>=2\n', + FAIL, + b'pyramid>=2\npyramid-foo==1\n', + ), + ( + b'a==1\n' + b'c>=1\n' + b'bbbb!=1\n' + b'c-a>=1;python_version>="3.6"\n' + b'e>=2\n' + b'd>2\n' + b'g<2\n' + b'f<=2\n', + FAIL, + b'a==1\n' + b'bbbb!=1\n' + b'c>=1\n' + b'c-a>=1;python_version>="3.6"\n' + b'd>2\n' + b'e>=2\n' + b'f<=2\n' + b'g<2\n', ), (b'ocflib\nDjango\nPyMySQL\n', FAIL, b'Django\nocflib\nPyMySQL\n'), ( From c8d9fb183f5ca704d24ecb6c7007f414d84656db Mon Sep 17 00:00:00 2001 From: Max Rozentsveyg Date: Mon, 18 May 2020 17:34:38 -0400 Subject: [PATCH 107/334] Fix C407 --- pre_commit_hooks/file_contents_sorter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 41ce306f..983ba016 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -20,7 +20,7 @@ def sort_file_contents(f: IO[bytes]) -> int: before = list(f) - after = sorted([line.strip(b'\n\r') for line in before if line.strip()]) + after = sorted(line.strip(b'\n\r') for line in before if line.strip()) before_string = b''.join(before) after_string = b'\n'.join(after) + b'\n' From 5195ba3449c076b7c9f0c264fb23d8e3a7ab9468 Mon Sep 17 00:00:00 2001 From: Max Rozentsveyg Date: Sat, 16 May 2020 23:59:08 -0400 Subject: [PATCH 108/334] Check git mode on Windows --- .../check_executables_have_shebangs.py | 67 +++++++++++----- tests/check_executables_have_shebangs_test.py | 77 ++++++++++++++++++- 2 files changed, 124 insertions(+), 20 deletions(-) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index c34c7b70..1c50ea02 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -2,26 +2,60 @@ 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.util import cmd_output -def check_has_shebang(path: str) -> int: +EXECUTABLE_VALUES = frozenset(('1', '3', '5', '7')) + + +def check_executables(paths: List[str]) -> int: + if sys.platform == 'win32': # pragma: win32 cover + return _check_git_filemode(paths) + else: # pragma: win32 no cover + retv = 0 + for path in paths: + if not _check_has_shebang(path): + _message(path) + retv = 1 + + return retv + + +def _check_git_filemode(paths: Sequence[str]) -> int: + outs = cmd_output('git', 'ls-files', '--stage', '--', *paths) + seen: Set[str] = set() + for out in outs.splitlines(): + metadata, path = out.split('\t') + tagmode = metadata.split(' ', 1)[0] + + is_executable = any(b in EXECUTABLE_VALUES for b in tagmode[-3:]) + has_shebang = _check_has_shebang(path) + if is_executable and not has_shebang: + _message(path) + seen.add(path) + + return int(bool(seen)) + + +def _check_has_shebang(path: str) -> int: with open(path, 'rb') as f: first_bytes = f.read(2) - if first_bytes != b'#!': - quoted = shlex.quote(path) - print( - f'{path}: marked executable but has no (or invalid) shebang!\n' - f" If it isn't supposed to be executable, try: " - f'`chmod -x {quoted}`\n' - f' If it is supposed to be executable, double-check its shebang.', - file=sys.stderr, - ) - return 1 - else: - return 0 + return first_bytes == b'#!' + + +def _message(path: str) -> None: + print( + f'{path}: marked executable but has no (or invalid) shebang!\n' + f" If it isn't supposed to be executable, try: " + f'`chmod -x {shlex.quote(path)}`\n' + f' If it is supposed to be executable, double-check its shebang.', + file=sys.stderr, + ) def main(argv: Optional[Sequence[str]] = None) -> int: @@ -29,12 +63,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) - retv = 0 - - for filename in args.filenames: - retv |= check_has_shebang(filename) - - return retv + return check_executables(args.filenames) if __name__ == '__main__': diff --git a/tests/check_executables_have_shebangs_test.py b/tests/check_executables_have_shebangs_test.py index 15f0c790..3b776128 100644 --- a/tests/check_executables_have_shebangs_test.py +++ b/tests/check_executables_have_shebangs_test.py @@ -1,8 +1,19 @@ +import os +import sys + import pytest +from pre_commit_hooks import check_executables_have_shebangs from pre_commit_hooks.check_executables_have_shebangs import main +from pre_commit_hooks.util import cmd_output + +skip_win32 = pytest.mark.skipif( + sys.platform == 'win32', + reason="non-git checks aren't relevant on windows", +) +@skip_win32 # pragma: win32 no cover @pytest.mark.parametrize( 'content', ( b'#!/bin/bash\nhello world\n', @@ -17,6 +28,7 @@ def test_has_shebang(content, tmpdir): assert main((path.strpath,)) == 0 +@skip_win32 # pragma: win32 no cover @pytest.mark.parametrize( 'content', ( b'', @@ -24,7 +36,6 @@ def test_has_shebang(content, tmpdir): b'\n#!python\n', b'python\n', '☃'.encode(), - ), ) def test_bad_shebang(content, tmpdir, capsys): @@ -33,3 +44,67 @@ def test_bad_shebang(content, tmpdir, capsys): assert main((path.strpath,)) == 1 _, stderr = capsys.readouterr() assert stderr.startswith(f'{path}: marked executable but') + + +def test_check_git_filemode_passing(tmpdir): + with tmpdir.as_cwd(): + cmd_output('git', 'init', '.') + + f = tmpdir.join('f') + f.write('#!/usr/bin/env bash') + f_path = str(f) + cmd_output('chmod', '+x', f_path) + cmd_output('git', 'add', f_path) + cmd_output('git', 'update-index', '--chmod=+x', f_path) + + g = tmpdir.join('g').ensure() + g_path = str(g) + cmd_output('git', 'add', g_path) + + # this is potentially a problem, but not something the script intends + # to check for -- we're only making sure that things that are + # executable have shebangs + h = tmpdir.join('h') + h.write('#!/usr/bin/env bash') + h_path = str(h) + cmd_output('git', 'add', h_path) + + files = (f_path, g_path, h_path) + assert check_executables_have_shebangs._check_git_filemode(files) == 0 + + +def test_check_git_filemode_failing(tmpdir): + with tmpdir.as_cwd(): + cmd_output('git', 'init', '.') + + f = tmpdir.join('f').ensure() + f_path = str(f) + cmd_output('chmod', '+x', f_path) + cmd_output('git', 'add', f_path) + cmd_output('git', 'update-index', '--chmod=+x', f_path) + + files = (f_path,) + assert check_executables_have_shebangs._check_git_filemode(files) == 1 + + +@pytest.mark.parametrize( + ('content', 'mode', 'expected'), + ( + pytest.param('#!python', '+x', 0, id='shebang with executable'), + pytest.param('#!python', '-x', 0, id='shebang without executable'), + pytest.param('', '+x', 1, id='no shebang with executable'), + pytest.param('', '-x', 0, id='no shebang without executable'), + ), +) +def test_git_executable_shebang(temp_git_dir, content, mode, expected): + with temp_git_dir.as_cwd(): + path = temp_git_dir.join('path') + path.write(content) + cmd_output('git', 'add', str(path)) + cmd_output('chmod', mode, str(path)) + cmd_output('git', 'update-index', f'--chmod={mode}', str(path)) + + # simulate how identify choses that something is executable + filenames = [path for path in [str(path)] if os.access(path, os.X_OK)] + + assert main(filenames) == expected From 7848fcff222198bdfeff61da436b08ca3f98d7fc Mon Sep 17 00:00:00 2001 From: Max R Date: Mon, 18 May 2020 21:46:53 -0400 Subject: [PATCH 109/334] Fix typo --- tests/check_executables_have_shebangs_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check_executables_have_shebangs_test.py b/tests/check_executables_have_shebangs_test.py index 3b776128..9c703343 100644 --- a/tests/check_executables_have_shebangs_test.py +++ b/tests/check_executables_have_shebangs_test.py @@ -104,7 +104,7 @@ def test_git_executable_shebang(temp_git_dir, content, mode, expected): cmd_output('chmod', mode, str(path)) cmd_output('git', 'update-index', f'--chmod={mode}', str(path)) - # simulate how identify choses that something is executable + # simulate how identify chooses that something is executable filenames = [path for path in [str(path)] if os.access(path, os.X_OK)] assert main(filenames) == expected From 926208fb31c7f4b6e718e20fc1f5789fd74dc3df Mon Sep 17 00:00:00 2001 From: Pedro Calleja Date: Mon, 18 May 2020 21:27:24 -0500 Subject: [PATCH 110/334] hotfix: the user may be define an extra arguments for a removed hook --- pre_commit_hooks/removed.py | 2 +- tests/removed_test.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/removed.py b/pre_commit_hooks/removed.py index 9710b2d6..60df0963 100644 --- a/pre_commit_hooks/removed.py +++ b/pre_commit_hooks/removed.py @@ -5,7 +5,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: argv = argv if argv is not None else sys.argv[1:] - hookid, new_hookid, url = argv + hookid, new_hookid, url = argv[:3] raise SystemExit( f'`{hookid}` has been removed -- use `{new_hookid}` from {url}', ) diff --git a/tests/removed_test.py b/tests/removed_test.py index 83df1647..d635eb1e 100644 --- a/tests/removed_test.py +++ b/tests/removed_test.py @@ -8,6 +8,7 @@ def test_always_fails(): main(( 'autopep8-wrapper', 'autopep8', 'https://github.com/pre-commit/mirrors-autopep8', + '--foo', 'bar', )) msg, = excinfo.value.args assert msg == ( From f35bfed79e837c5f11cd8e7abfdb8f188dd9b3bb Mon Sep 17 00:00:00 2001 From: Max Rozentsveyg Date: Wed, 20 May 2020 12:07:45 -0400 Subject: [PATCH 111/334] Don't use LocalPath.strpath --- tests/check_added_large_files_test.py | 4 ++-- tests/check_builtin_literals_test.py | 6 +++--- tests/check_byte_order_marker_test.py | 4 ++-- tests/check_docstring_first_test.py | 6 +++--- tests/check_executables_have_shebangs_test.py | 4 ++-- tests/check_merge_conflict_test.py | 8 ++++---- tests/check_symlinks_test.py | 4 ++-- tests/check_toml_test.py | 6 +++--- tests/check_vcs_permalinks_test.py | 4 ++-- tests/check_yaml_test.py | 12 ++++++------ tests/conftest.py | 2 +- tests/debug_statement_hook_test.py | 6 +++--- tests/detect_private_key_test.py | 2 +- tests/end_of_file_fixer_test.py | 2 +- tests/file_contents_sorter_test.py | 2 +- tests/fix_encoding_pragma_test.py | 16 ++++++++-------- tests/forbid_new_submodules_test.py | 2 +- tests/mixed_line_ending_test.py | 16 ++++++++-------- tests/pretty_format_json_test.py | 6 +++--- tests/requirements_txt_fixer_test.py | 2 +- tests/sort_simple_yaml_test.py | 2 +- tests/string_fixer_test.py | 4 ++-- tests/trailing_whitespace_fixer_test.py | 18 +++++++++--------- 23 files changed, 69 insertions(+), 69 deletions(-) diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index c33a9ca4..40ffd24d 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -75,7 +75,7 @@ def has_gitlfs(): @xfailif_no_gitlfs def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv('HOME', str(temp_git_dir.strpath)) + monkeypatch.setenv('HOME', str(temp_git_dir)) cmd_output('git', 'lfs', 'install') temp_git_dir.join('f.py').write('a' * 10000) cmd_output('git', 'lfs', 'track', 'f.py') @@ -87,7 +87,7 @@ def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover @xfailif_no_gitlfs def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv('HOME', str(temp_git_dir.strpath)) + monkeypatch.setenv('HOME', str(temp_git_dir)) cmd_output('git', 'lfs', 'install') cmd_output('git', 'lfs', 'track', 'a.bin', 'b.bin') # First add the file we're going to move diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py index 01193e83..e9367989 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -131,19 +131,19 @@ def test_ignore_constructors(): def test_failing_file(tmpdir): f = tmpdir.join('f.py') f.write(BUILTIN_CONSTRUCTORS) - rc = main([f.strpath]) + rc = main([str(f)]) assert rc == 1 def test_passing_file(tmpdir): f = tmpdir.join('f.py') f.write(BUILTIN_LITERALS) - rc = main([f.strpath]) + rc = main([str(f)]) assert rc == 0 def test_failing_file_ignore_all(tmpdir): f = tmpdir.join('f.py') f.write(BUILTIN_CONSTRUCTORS) - rc = main(['--ignore=complex,dict,float,int,list,str,tuple', f.strpath]) + rc = main(['--ignore=complex,dict,float,int,list,str,tuple', str(f)]) assert rc == 0 diff --git a/tests/check_byte_order_marker_test.py b/tests/check_byte_order_marker_test.py index 9995200a..4c402476 100644 --- a/tests/check_byte_order_marker_test.py +++ b/tests/check_byte_order_marker_test.py @@ -4,10 +4,10 @@ def test_failure(tmpdir): f = tmpdir.join('f.txt') f.write_text('ohai', encoding='utf-8-sig') - assert check_byte_order_marker.main((f.strpath,)) == 1 + assert check_byte_order_marker.main((str(f),)) == 1 def test_success(tmpdir): f = tmpdir.join('f.txt') f.write_text('ohai', encoding='utf-8') - assert check_byte_order_marker.main((f.strpath,)) == 0 + assert check_byte_order_marker.main((str(f),)) == 0 diff --git a/tests/check_docstring_first_test.py b/tests/check_docstring_first_test.py index 7ad876ff..ed5c08ef 100644 --- a/tests/check_docstring_first_test.py +++ b/tests/check_docstring_first_test.py @@ -56,12 +56,12 @@ def test_unit(capsys, contents, expected, expected_out): def test_integration(tmpdir, capsys, contents, expected, expected_out): f = tmpdir.join('test.py') f.write_binary(contents) - assert main([f.strpath]) == expected - assert capsys.readouterr()[0] == expected_out.format(filename=f.strpath) + assert main([str(f)]) == expected + assert capsys.readouterr()[0] == expected_out.format(filename=str(f)) def test_arbitrary_encoding(tmpdir): f = tmpdir.join('f.py') contents = '# -*- coding: cp1252\nx = "£"'.encode('cp1252') f.write_binary(contents) - assert main([f.strpath]) == 0 + assert main([str(f)]) == 0 diff --git a/tests/check_executables_have_shebangs_test.py b/tests/check_executables_have_shebangs_test.py index 9c703343..5895a2ae 100644 --- a/tests/check_executables_have_shebangs_test.py +++ b/tests/check_executables_have_shebangs_test.py @@ -25,7 +25,7 @@ def test_has_shebang(content, tmpdir): path = tmpdir.join('path') path.write(content, 'wb') - assert main((path.strpath,)) == 0 + assert main((str(path),)) == 0 @skip_win32 # pragma: win32 no cover @@ -41,7 +41,7 @@ def test_has_shebang(content, tmpdir): def test_bad_shebang(content, tmpdir, capsys): path = tmpdir.join('path') path.write(content, 'wb') - assert main((path.strpath,)) == 1 + assert main((str(path),)) == 1 _, stderr = capsys.readouterr() assert stderr.startswith(f'{path}: marked executable but') diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index 9968507b..fccf41ff 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -16,13 +16,13 @@ def f1_is_a_conflict_file(tmpdir): repo2 = tmpdir.join('repo2') repo2_f1 = repo2.join('f1') - cmd_output('git', 'init', '--', repo1.strpath) + cmd_output('git', 'init', '--', str(repo1)) with repo1.as_cwd(): repo1_f1.ensure() cmd_output('git', 'add', '.') cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'commit1') - cmd_output('git', 'clone', repo1.strpath, repo2.strpath) + cmd_output('git', 'clone', str(repo1), str(repo2)) # Commit in master with repo1.as_cwd(): @@ -71,13 +71,13 @@ def repository_pending_merge(tmpdir): repo2 = tmpdir.join('repo2') repo2_f1 = repo2.join('f1') repo2_f2 = repo2.join('f2') - cmd_output('git', 'init', repo1.strpath) + cmd_output('git', 'init', str(repo1)) with repo1.as_cwd(): repo1_f1.ensure() cmd_output('git', 'add', '.') cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'commit1') - cmd_output('git', 'clone', repo1.strpath, repo2.strpath) + cmd_output('git', 'clone', str(repo1), str(repo2)) # Commit in master with repo1.as_cwd(): diff --git a/tests/check_symlinks_test.py b/tests/check_symlinks_test.py index ecbc7aec..07c11687 100644 --- a/tests/check_symlinks_test.py +++ b/tests/check_symlinks_test.py @@ -16,8 +16,8 @@ def test_main(tmpdir, dest, expected): # pragma: no cover (symlinks) tmpdir.join('exists').ensure() symlink = tmpdir.join('symlink') symlink.mksymlinkto(tmpdir.join(dest)) - assert main((symlink.strpath,)) == expected + assert main((str(symlink),)) == expected def test_main_normal_file(tmpdir): - assert main((tmpdir.join('f').ensure().strpath,)) == 0 + assert main((str(tmpdir.join('f').ensure()),)) == 0 diff --git a/tests/check_toml_test.py b/tests/check_toml_test.py index 32837176..c7251eb0 100644 --- a/tests/check_toml_test.py +++ b/tests/check_toml_test.py @@ -8,7 +8,7 @@ def test_toml_bad(tmpdir): = "no key name" # INVALID """) - ret = main((filename.strpath,)) + ret = main((str(filename),)) assert ret == 1 @@ -25,12 +25,12 @@ def test_toml_good(tmpdir): dob = 1979-05-27T07:32:00-08:00 # First class dates """, ) - ret = main((filename.strpath,)) + ret = main((str(filename),)) assert ret == 0 def test_toml_good_unicode(tmpdir): filename = tmpdir.join('f') filename.write_binary('letter = "\N{SNOWMAN}"\n'.encode()) - ret = main((filename.strpath,)) + ret = main((str(filename),)) assert ret == 0 diff --git a/tests/check_vcs_permalinks_test.py b/tests/check_vcs_permalinks_test.py index b893c98f..19b1c355 100644 --- a/tests/check_vcs_permalinks_test.py +++ b/tests/check_vcs_permalinks_test.py @@ -3,7 +3,7 @@ def test_trivial(tmpdir): f = tmpdir.join('f.txt').ensure() - assert not main((f.strpath,)) + assert not main((str(f),)) def test_passing(tmpdir): @@ -16,7 +16,7 @@ def test_passing(tmpdir): # regression test for overly-greedy regex b'https://github.com/ yes / no ? /blob/master/foo#L1\n', ) - assert not main((f.strpath,)) + assert not main((str(f),)) def test_failing(tmpdir, capsys): diff --git a/tests/check_yaml_test.py b/tests/check_yaml_test.py index 2f869d15..1a017a12 100644 --- a/tests/check_yaml_test.py +++ b/tests/check_yaml_test.py @@ -20,16 +20,16 @@ def test_main_allow_multiple_documents(tmpdir): f.write('---\nfoo\n---\nbar\n') # should fail without the setting - assert main((f.strpath,)) + assert main((str(f),)) # should pass when we allow multiple documents - assert not main(('--allow-multiple-documents', f.strpath)) + assert not main(('--allow-multiple-documents', str(f))) def test_fails_even_with_allow_multiple_documents(tmpdir): f = tmpdir.join('test.yaml') f.write('[') - assert main(('--allow-multiple-documents', f.strpath)) + assert main(('--allow-multiple-documents', str(f))) def test_main_unsafe(tmpdir): @@ -40,12 +40,12 @@ def test_main_unsafe(tmpdir): ' deadbeefdeadbeefdeadbeef\n', ) # should fail "safe" check - assert main((f.strpath,)) + assert main((str(f),)) # should pass when we allow unsafe documents - assert not main(('--unsafe', f.strpath)) + assert not main(('--unsafe', str(f))) def test_main_unsafe_still_fails_on_syntax_errors(tmpdir): f = tmpdir.join('test.yaml') f.write('[') - assert main(('--unsafe', f.strpath)) + assert main(('--unsafe', str(f))) diff --git a/tests/conftest.py b/tests/conftest.py index f98ae349..f92cfc18 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,5 +6,5 @@ @pytest.fixture def temp_git_dir(tmpdir): git_dir = tmpdir.join('gits') - cmd_output('git', 'init', '--', git_dir.strpath) + cmd_output('git', 'init', '--', str(git_dir)) yield git_dir diff --git a/tests/debug_statement_hook_test.py b/tests/debug_statement_hook_test.py index f2cabc1d..428421a0 100644 --- a/tests/debug_statement_hook_test.py +++ b/tests/debug_statement_hook_test.py @@ -33,7 +33,7 @@ def test_finds_breakpoint(): def test_returns_one_for_failing_file(tmpdir): f_py = tmpdir.join('f.py') f_py.write('def f():\n import pdb; pdb.set_trace()') - ret = main([f_py.strpath]) + ret = main([str(f_py)]) assert ret == 1 @@ -50,10 +50,10 @@ def test_syntaxerror_file(): def test_non_utf8_file(tmpdir): f_py = tmpdir.join('f.py') f_py.write_binary('# -*- coding: cp1252 -*-\nx = "€"\n'.encode('cp1252')) - assert main((f_py.strpath,)) == 0 + assert main((str(f_py),)) == 0 def test_py37_breakpoint(tmpdir): f_py = tmpdir.join('f.py') f_py.write('def f():\n breakpoint()\n') - assert main((f_py.strpath,)) == 1 + assert main((str(f_py),)) == 1 diff --git a/tests/detect_private_key_test.py b/tests/detect_private_key_test.py index 9266f2b0..72810008 100644 --- a/tests/detect_private_key_test.py +++ b/tests/detect_private_key_test.py @@ -21,4 +21,4 @@ def test_main(input_s, expected_retval, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - assert main([path.strpath]) == expected_retval + assert main([str(path)]) == expected_retval diff --git a/tests/end_of_file_fixer_test.py b/tests/end_of_file_fixer_test.py index 7f644e76..60b9e82f 100644 --- a/tests/end_of_file_fixer_test.py +++ b/tests/end_of_file_fixer_test.py @@ -35,7 +35,7 @@ def test_integration(input_s, expected_retval, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - ret = main([path.strpath]) + ret = main([str(path)]) file_output = path.read_binary() assert file_output == output diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py index 1f9a14b4..c8afc2d8 100644 --- a/tests/file_contents_sorter_test.py +++ b/tests/file_contents_sorter_test.py @@ -27,7 +27,7 @@ def test_integration(input_s, expected_retval, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - output_retval = main([path.strpath]) + output_retval = main([str(path)]) assert path.read_binary() == output assert output_retval == expected_retval diff --git a/tests/fix_encoding_pragma_test.py b/tests/fix_encoding_pragma_test.py index f3531f26..f3afa094 100644 --- a/tests/fix_encoding_pragma_test.py +++ b/tests/fix_encoding_pragma_test.py @@ -11,7 +11,7 @@ def test_integration_inserting_pragma(tmpdir): path = tmpdir.join('foo.py') path.write_binary(b'import httplib\n') - assert main((path.strpath,)) == 1 + assert main((str(path),)) == 1 assert path.read_binary() == ( b'# -*- coding: utf-8 -*-\n' @@ -22,14 +22,14 @@ def test_integration_inserting_pragma(tmpdir): def test_integration_ok(tmpdir): path = tmpdir.join('foo.py') path.write_binary(b'# -*- coding: utf-8 -*-\nx = 1\n') - assert main((path.strpath,)) == 0 + assert main((str(path),)) == 0 def test_integration_remove(tmpdir): path = tmpdir.join('foo.py') path.write_binary(b'# -*- coding: utf-8 -*-\nx = 1\n') - assert main((path.strpath, '--remove')) == 1 + assert main((str(path), '--remove')) == 1 assert path.read_binary() == b'x = 1\n' @@ -37,7 +37,7 @@ def test_integration_remove(tmpdir): def test_integration_remove_ok(tmpdir): path = tmpdir.join('foo.py') path.write_binary(b'x = 1\n') - assert main((path.strpath, '--remove')) == 0 + assert main((str(path), '--remove')) == 0 @pytest.mark.parametrize( @@ -140,20 +140,20 @@ def test_integration_alternate_pragma(tmpdir, capsys): f.write('x = 1\n') pragma = '# coding: utf-8' - assert main((f.strpath, '--pragma', pragma)) == 1 + assert main((str(f), '--pragma', pragma)) == 1 assert f.read() == '# coding: utf-8\nx = 1\n' out, _ = capsys.readouterr() - assert out == f'Added `# coding: utf-8` to {f.strpath}\n' + assert out == f'Added `# coding: utf-8` to {str(f)}\n' def test_crlf_ok(tmpdir): f = tmpdir.join('f.py') f.write_binary(b'# -*- coding: utf-8 -*-\r\nx = 1\r\n') - assert not main((f.strpath,)) + assert not main((str(f),)) def test_crfl_adds(tmpdir): f = tmpdir.join('f.py') f.write_binary(b'x = 1\r\n') - assert main((f.strpath,)) + assert main((str(f),)) assert f.read_binary() == b'# -*- coding: utf-8 -*-\r\nx = 1\r\n' diff --git a/tests/forbid_new_submodules_test.py b/tests/forbid_new_submodules_test.py index 76191820..4871ae7f 100644 --- a/tests/forbid_new_submodules_test.py +++ b/tests/forbid_new_submodules_test.py @@ -15,7 +15,7 @@ def git_dir_with_git_dir(tmpdir): subprocess.check_call(('git', 'init', 'foo')) subprocess.check_call( ('git', 'commit', '-m', 'init', '--allow-empty', '--no-gpg-sign'), - cwd=tmpdir.join('foo').strpath, + cwd=str(tmpdir.join('foo')), ) yield diff --git a/tests/mixed_line_ending_test.py b/tests/mixed_line_ending_test.py index c438f745..f1c26418 100644 --- a/tests/mixed_line_ending_test.py +++ b/tests/mixed_line_ending_test.py @@ -25,7 +25,7 @@ def test_mixed_line_ending_fixes_auto(input_s, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - ret = main((path.strpath,)) + ret = main((str(path),)) assert ret == 1 assert path.read_binary() == output @@ -34,7 +34,7 @@ def test_mixed_line_ending_fixes_auto(input_s, output, tmpdir): def test_non_mixed_no_newline_end_of_file(tmpdir): path = tmpdir.join('f.txt') path.write_binary(b'foo\nbar\nbaz') - assert not main((path.strpath,)) + assert not main((str(path),)) # the hook *could* fix the end of the file, but leaves it alone # this is mostly to document the current behaviour assert path.read_binary() == b'foo\nbar\nbaz' @@ -43,7 +43,7 @@ def test_non_mixed_no_newline_end_of_file(tmpdir): def test_mixed_no_newline_end_of_file(tmpdir): path = tmpdir.join('f.txt') path.write_binary(b'foo\r\nbar\nbaz') - assert main((path.strpath,)) + assert main((str(path),)) # the hook rewrites the end of the file, this is slightly inconsistent # with the non-mixed case but I think this is the better behaviour # this is mostly to document the current behaviour @@ -66,7 +66,7 @@ def test_mixed_no_newline_end_of_file(tmpdir): def test_line_endings_ok(fix_option, input_s, tmpdir, capsys): path = tmpdir.join('input.txt') path.write_binary(input_s) - ret = main((fix_option, path.strpath)) + ret = main((fix_option, str(path))) assert ret == 0 assert path.read_binary() == input_s @@ -78,7 +78,7 @@ def test_no_fix_does_not_modify(tmpdir, capsys): path = tmpdir.join('input.txt') contents = b'foo\r\nbar\rbaz\nwomp\n' path.write_binary(contents) - ret = main(('--fix=no', path.strpath)) + ret = main(('--fix=no', str(path))) assert ret == 1 assert path.read_binary() == contents @@ -89,7 +89,7 @@ def test_no_fix_does_not_modify(tmpdir, capsys): def test_fix_lf(tmpdir, capsys): path = tmpdir.join('input.txt') path.write_binary(b'foo\r\nbar\rbaz\n') - ret = main(('--fix=lf', path.strpath)) + ret = main(('--fix=lf', str(path))) assert ret == 1 assert path.read_binary() == b'foo\nbar\nbaz\n' @@ -100,7 +100,7 @@ def test_fix_lf(tmpdir, capsys): def test_fix_crlf(tmpdir): path = tmpdir.join('input.txt') path.write_binary(b'foo\r\nbar\rbaz\n') - ret = main(('--fix=crlf', path.strpath)) + ret = main(('--fix=crlf', str(path))) assert ret == 1 assert path.read_binary() == b'foo\r\nbar\r\nbaz\r\n' @@ -110,7 +110,7 @@ def test_fix_lf_all_crlf(tmpdir): """Regression test for #239""" path = tmpdir.join('input.txt') path.write_binary(b'foo\r\nbar\r\n') - ret = main(('--fix=lf', path.strpath)) + ret = main(('--fix=lf', str(path))) assert ret == 1 assert path.read_binary() == b'foo\nbar\n' diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 59a87f0e..7fda23b3 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -67,16 +67,16 @@ def test_autofix_main(tmpdir): srcfile = tmpdir.join('to_be_json_formatted.json') shutil.copyfile( get_resource_path('not_pretty_formatted_json.json'), - srcfile.strpath, + str(srcfile), ) # now launch the autofix on that file - ret = main(['--autofix', srcfile.strpath]) + ret = main(['--autofix', str(srcfile)]) # it should have formatted it assert ret == 1 # file was formatted (shouldn't trigger linter again) - ret = main([srcfile.strpath]) + ret = main([str(srcfile)]) assert ret == 0 diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index fae5a723..f4f679da 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -93,7 +93,7 @@ def test_integration(input_s, expected_retval, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - output_retval = main([path.strpath]) + output_retval = main([str(path)]) assert path.read_binary() == output assert output_retval == expected_retval diff --git a/tests/sort_simple_yaml_test.py b/tests/sort_simple_yaml_test.py index 77e95d50..a682c158 100644 --- a/tests/sort_simple_yaml_test.py +++ b/tests/sort_simple_yaml_test.py @@ -39,7 +39,7 @@ @pytest.mark.parametrize('bad_lines,good_lines,retval', TEST_SORTS) def test_integration_good_bad_lines(tmpdir, bad_lines, good_lines, retval): - file_path = os.path.join(tmpdir.strpath, 'foo.yaml') + file_path = os.path.join(str(tmpdir), 'foo.yaml') with open(file_path, 'w') as f: f.write('\n'.join(bad_lines) + '\n') diff --git a/tests/string_fixer_test.py b/tests/string_fixer_test.py index 77a51cf0..6ddb0ac8 100644 --- a/tests/string_fixer_test.py +++ b/tests/string_fixer_test.py @@ -42,7 +42,7 @@ def test_rewrite(input_s, output, expected_retval, tmpdir): path = tmpdir.join('file.py') path.write(input_s) - retval = main([path.strpath]) + retval = main([str(path)]) assert path.read() == output assert retval == expected_retval @@ -50,5 +50,5 @@ def test_rewrite(input_s, output, expected_retval, tmpdir): def test_rewrite_crlf(tmpdir): f = tmpdir.join('f.py') f.write_binary(b'"foo"\r\n"bar"\r\n') - assert main((f.strpath,)) + assert main((str(f),)) assert f.read_binary() == b"'foo'\r\n'bar'\r\n" diff --git a/tests/trailing_whitespace_fixer_test.py b/tests/trailing_whitespace_fixer_test.py index 53177ac9..bb3b62d4 100644 --- a/tests/trailing_whitespace_fixer_test.py +++ b/tests/trailing_whitespace_fixer_test.py @@ -13,14 +13,14 @@ def test_fixes_trailing_whitespace(input_s, expected, tmpdir): path = tmpdir.join('file.md') path.write(input_s) - assert main((path.strpath,)) == 1 + assert main((str(path),)) == 1 assert path.read() == expected def test_ok_no_newline_end_of_file(tmpdir): filename = tmpdir.join('f') filename.write_binary(b'foo\nbar') - ret = main((filename.strpath,)) + ret = main((str(filename),)) assert filename.read_binary() == b'foo\nbar' assert ret == 0 @@ -28,7 +28,7 @@ def test_ok_no_newline_end_of_file(tmpdir): def test_ok_with_dos_line_endings(tmpdir): filename = tmpdir.join('f') filename.write_binary(b'foo\r\nbar\r\nbaz\r\n') - ret = main((filename.strpath,)) + ret = main((str(filename),)) assert filename.read_binary() == b'foo\r\nbar\r\nbaz\r\n' assert ret == 0 @@ -43,7 +43,7 @@ def test_fixes_markdown_files(tmpdir, ext): '\t\n' # trailing tabs are stripped anyway '\n ', # whitespace at the end of the file is removed ) - ret = main((path.strpath, f'--markdown-linebreak-ext={ext}')) + ret = main((str(path), f'--markdown-linebreak-ext={ext}')) assert ret == 1 assert path.read() == ( 'foo \n' @@ -63,7 +63,7 @@ def test_markdown_linebreak_ext_badopt(arg): def test_prints_warning_with_no_markdown_ext(capsys, tmpdir): f = tmpdir.join('f').ensure() - assert main((f.strpath, '--no-markdown-linebreak-ext')) == 0 + assert main((str(f), '--no-markdown-linebreak-ext')) == 0 out, _ = capsys.readouterr() assert out == '--no-markdown-linebreak-ext now does nothing!\n' @@ -72,7 +72,7 @@ def test_preserve_non_utf8_file(tmpdir): non_utf8_bytes_content = b'\xe9 \n\n' path = tmpdir.join('file.txt') path.write_binary(non_utf8_bytes_content) - ret = main([path.strpath]) + ret = main([str(path)]) assert ret == 1 assert path.size() == (len(non_utf8_bytes_content) - 1) @@ -81,7 +81,7 @@ def test_custom_charset_change(tmpdir): # strip spaces only, no tabs path = tmpdir.join('file.txt') path.write('\ta \t \n') - ret = main([path.strpath, '--chars', ' ']) + ret = main([str(path), '--chars', ' ']) assert ret == 1 assert path.read() == '\ta \t\n' @@ -89,13 +89,13 @@ def test_custom_charset_change(tmpdir): def test_custom_charset_no_change(tmpdir): path = tmpdir.join('file.txt') path.write('\ta \t\n') - ret = main([path.strpath, '--chars', ' ']) + ret = main([str(path), '--chars', ' ']) assert ret == 0 def test_markdown_with_custom_charset(tmpdir): path = tmpdir.join('file.md') path.write('\ta \t \n') - ret = main([path.strpath, '--chars', ' ', '--markdown-linebreak-ext', '*']) + ret = main([str(path), '--chars', ' ', '--markdown-linebreak-ext', '*']) assert ret == 1 assert path.read() == '\ta \t \n' From ebc15addedad713c86ef18ae9632c88e187dd0af Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 20 May 2020 09:11:02 -0700 Subject: [PATCH 112/334] v3.1.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 17 +++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c5ccc795..1e118f4e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.0.1 + rev: v3.1.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 14230f26..8e455117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +3.1.0 - 2020-05-20 +================== + +### Features +- `check-executables-have-shebangs`: on windows, validate the mode bits using + `git` + - #480 PR by @mxr. + - #435 issue by @dstandish. +- `requirements-txt-fixer`: support more operators + - #483 PR by @mxr. + - #331 issue by @hackedd. + +### Fixes +- `pre-commit-hooks-removed`: Fix when removed hooks used `args` + - #487 PR by @pedrocalleja. + - #485 issue by @pedrocalleja. + 3.0.1 - 2020-05-16 ================== diff --git a/README.md b/README.md index 54db3a99..6c7fba92 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.0.1 # Use the ref you want to point at + rev: v3.1.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index cf046894..0f7721f9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 3.0.1 +version = 3.1.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 1da4a7f2963f9c77c31be66a76bf6b776f06d470 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 26 May 2020 21:53:22 -0700 Subject: [PATCH 113/334] slightly speed up tests by avoiding pre-commit install Committed via https://github.com/asottile/all-repos --- requirements-dev.txt | 1 - tox.ini | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 67f6485d..0c5a37eb 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,3 @@ covdefaults coverage -pre-commit pytest diff --git a/tox.ini b/tox.ini index cb58fee6..965eba92 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,6 @@ commands = coverage erase coverage run -m pytest {posargs:tests} coverage report --fail-under 100 - pre-commit install [testenv:pre-commit] skip_install = true From c14b3aa54f363de44ff6f8b837186d53ef1435f7 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 17 Jun 2020 08:27:11 -0700 Subject: [PATCH 114/334] sed -i s/whitelist/allowlist/g --- pre_commit_hooks/file_contents_sorter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 983ba016..76dc4fa1 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -2,7 +2,7 @@ A very simple pre-commit hook that, when passed one or more filenames as arguments, will sort the lines in those files. -An example use case for this: you have a deploy-whitelist.txt file +An example use case for this: you have a deploy-allowlist.txt file in a repo that contains a list of filenames that is used to specify files to be included in a docker container. This file has one filename per line. Various users are adding/removing lines from this file; using From b4694348b0c4e41f9bfc94d98283e6d6780eb58f Mon Sep 17 00:00:00 2001 From: Marc Jay Date: Fri, 19 Jun 2020 18:34:16 +0100 Subject: [PATCH 115/334] Document the default always_run behaviour of no-commit-to-branch Include instructions on how to use files/types/excludes/exclude_types with the no-commit-to-branch hook, along with the caveat of it allowing empty commits --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c7fba92..2582f9a1 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,13 @@ Protect specific branches from direct checkins. - `-p` / `--pattern` can be used to protect branches that match a supplied regex (e.g. `--pattern, release/.*`). May be specified multiple times. +Note that `no-commit-to-branch` is configured by default to [`always_run`](https://pre-commit.com/#config-always_run). +As a result, it will ignore any setting of [`files`](https://pre-commit.com/#config-files), +[`exclude`](https://pre-commit.com/#config-exclude), [`types`](https://pre-commit.com/#config-types) +or [`exclude_types`](https://pre-commit.com/#config-exclude_types). +Set [`always_run: false`](https://pre-commit.com/#config-always_run) to allow this hook to be skipped according to these +file filters. Caveat: In this configuration, empty commits (`git commit --allow-empty`) would always be allowed by this hook. + #### `pretty-format-json` Checks that all your JSON files are pretty. "Pretty" here means that keys are sorted and indented. You can configure this with @@ -150,7 +157,7 @@ Sorts simple YAML files which consist only of top-level keys, preserving comments and blocks. Note that `sort-simple-yaml` by default matches no `files` as it enforces a -very specific format. You must opt in to this by setting `files`, for example: +very specific format. You must opt in to this by setting [`files`](https://pre-commit.com/#config-files), for example: ```yaml - id: sort-simple-yaml From 53a05b952c910d53b5e839d4c267d9fc3f352979 Mon Sep 17 00:00:00 2001 From: Jascha Geerds Date: Wed, 1 Jul 2020 17:15:46 +0200 Subject: [PATCH 116/334] Add "pydevd_pycharm" to list of debug statements --- pre_commit_hooks/debug_statement_hook.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 6d2dc827..794f7080 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -7,7 +7,16 @@ from typing import Sequence -DEBUG_STATEMENTS = {'pdb', 'ipdb', 'pudb', 'q', 'rdb', 'rpdb', 'wdb'} +DEBUG_STATEMENTS = { + 'ipdb', + 'pdb', + 'pudb', + 'pydevd_pycharm', + 'q', + 'rdb', + 'rpdb', + 'wdb', +} class Debug(NamedTuple): From 4faed34fbc8b599490619cdf310a327c3f3c043f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 29 Jul 2020 09:57:24 +0200 Subject: [PATCH 117/334] Fix parsing of git output with unusual characters On Windows, all files are "executable". Therefore, to know if a file is supposed to be executed, we check how its attributes were recorded by git: we run a `git ls-files` command in a subprocess. By default, this command outputs information on multiple lines (file and their data separated by newlines). When a file contains an unusual character, the character is escaped with an integer sequence (such as `\303\261`), and git wraps the whole filename in double-quotes because of the backslashes. It breaks the current code because we try to open the filename containing the double-quotes: it doesn't exist, of course. Instead of trying to fix this special case by removing the double-quotes, and breaking other cases (a double-quote is a valid filename character on Linux), we tell git to separate each item with the null character `\0` instead of a new line `\n`, with the option `-z`. With this option, git doesn't escape unusual characters with integer sequence, so the output is fixed, and we parse it by splitting on `\0` instead of `\n`. Fixes #508. --- .../check_executables_have_shebangs.py | 12 +++++++-- tests/check_executables_have_shebangs_test.py | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index 1c50ea02..a02d2a9c 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -12,6 +12,14 @@ EXECUTABLE_VALUES = frozenset(('1', '3', '5', '7')) +def zsplit(s: str) -> List[str]: + s = s.strip('\0') + if s: + return s.split('\0') + else: + return [] + + def check_executables(paths: List[str]) -> int: if sys.platform == 'win32': # pragma: win32 cover return _check_git_filemode(paths) @@ -26,9 +34,9 @@ def check_executables(paths: List[str]) -> int: def _check_git_filemode(paths: Sequence[str]) -> int: - outs = cmd_output('git', 'ls-files', '--stage', '--', *paths) + outs = cmd_output('git', 'ls-files', '-z', '--stage', '--', *paths) seen: Set[str] = set() - for out in outs.splitlines(): + for out in zsplit(outs): metadata, path = out.split('\t') tagmode = metadata.split(' ', 1)[0] diff --git a/tests/check_executables_have_shebangs_test.py b/tests/check_executables_have_shebangs_test.py index 5895a2ae..7046081f 100644 --- a/tests/check_executables_have_shebangs_test.py +++ b/tests/check_executables_have_shebangs_test.py @@ -73,6 +73,21 @@ def test_check_git_filemode_passing(tmpdir): assert check_executables_have_shebangs._check_git_filemode(files) == 0 +def test_check_git_filemode_passing_unusual_characters(tmpdir): + with tmpdir.as_cwd(): + cmd_output('git', 'init', '.') + + f = tmpdir.join('mañana.txt') + f.write('#!/usr/bin/env bash') + f_path = str(f) + cmd_output('chmod', '+x', f_path) + cmd_output('git', 'add', f_path) + cmd_output('git', 'update-index', '--chmod=+x', f_path) + + files = (f_path,) + assert check_executables_have_shebangs._check_git_filemode(files) == 0 + + def test_check_git_filemode_failing(tmpdir): with tmpdir.as_cwd(): cmd_output('git', 'init', '.') @@ -87,6 +102,16 @@ def test_check_git_filemode_failing(tmpdir): assert check_executables_have_shebangs._check_git_filemode(files) == 1 +@pytest.mark.parametrize('out', ('\0f1\0f2\0', '\0f1\0f2', 'f1\0f2\0')) +def test_check_zsplits_correctly(out): + assert check_executables_have_shebangs.zsplit(out) == ['f1', 'f2'] + + +@pytest.mark.parametrize('out', ('\0\0', '\0', '')) +def test_check_zsplit_returns_empty(out): + assert check_executables_have_shebangs.zsplit(out) == [] + + @pytest.mark.parametrize( ('content', 'mode', 'expected'), ( From e1668fe86af3810fbca72b8653fe478e66a0afdc Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 30 Jul 2020 13:33:26 -0700 Subject: [PATCH 118/334] v3.2.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 13 +++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1e118f4e..b4614a74 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.1.0 + rev: v3.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e455117..9aa7441b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +3.2.0 - 2020-07-30 +================== + +### Features +- `debug-statements`: add support for `pydevd_pycharm` debugger + - #502 PR by @jgeerds. + +### Fixes +- `check-executables-have-shebangs`: fix git-quoted files on windows (spaces, + non-ascii, etc.) + - #509 PR by @pawamoy. + - #508 issue by @pawamoy. + 3.1.0 - 2020-05-20 ================== diff --git a/README.md b/README.md index 2582f9a1..3552721f 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.1.0 # Use the ref you want to point at + rev: v3.2.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 0f7721f9..47b8bb6d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 3.1.0 +version = 3.2.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 0c760253f34db9998371ec434ef6059c54f7ddbf Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 26 Aug 2020 20:28:26 -0400 Subject: [PATCH 119/334] Add a way to do case-insensitive sorting via file-contents-sorter. --- pre_commit_hooks/file_contents_sorter.py | 21 +++++++-- tests/file_contents_sorter_test.py | 56 +++++++++++++++++------- 2 files changed, 58 insertions(+), 19 deletions(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 76dc4fa1..4c1c7479 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -10,6 +10,8 @@ conflicts and keep the file nicely ordered. """ import argparse +from typing import Any +from typing import Callable from typing import IO from typing import Optional from typing import Sequence @@ -18,9 +20,15 @@ FAIL = 1 -def sort_file_contents(f: IO[bytes]) -> int: +def sort_file_contents( + f: IO[bytes], + key: Optional[Callable[[bytes], Any]], +) -> int: before = list(f) - after = sorted(line.strip(b'\n\r') for line in before if line.strip()) + after = sorted( + (line.strip(b'\n\r') for line in before if line.strip()), + key=key, + ) before_string = b''.join(before) after_string = b'\n'.join(after) + b'\n' @@ -37,13 +45,20 @@ def sort_file_contents(f: IO[bytes]) -> int: def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='+', help='Files to sort') + parser.add_argument( + '--ignore-case', + action='store_const', + const=bytes.lower, + default=None, + help='fold lower case to upper case characters', + ) args = parser.parse_args(argv) retv = PASS for arg in args.filenames: with open(arg, 'rb+') as file_obj: - ret_for_file = sort_file_contents(file_obj) + ret_for_file = sort_file_contents(file_obj, key=args.ignore_case) if ret_for_file: print(f'Sorting {arg}') diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py index c8afc2d8..9ebb021a 100644 --- a/tests/file_contents_sorter_test.py +++ b/tests/file_contents_sorter_test.py @@ -6,28 +6,52 @@ @pytest.mark.parametrize( - ('input_s', 'expected_retval', 'output'), + ('input_s', 'argv', 'expected_retval', 'output'), ( - (b'', FAIL, b'\n'), - (b'lonesome\n', PASS, b'lonesome\n'), - (b'missing_newline', FAIL, b'missing_newline\n'), - (b'newline\nmissing', FAIL, b'missing\nnewline\n'), - (b'missing\nnewline', FAIL, b'missing\nnewline\n'), - (b'alpha\nbeta\n', PASS, b'alpha\nbeta\n'), - (b'beta\nalpha\n', FAIL, b'alpha\nbeta\n'), - (b'C\nc\n', PASS, b'C\nc\n'), - (b'c\nC\n', FAIL, b'C\nc\n'), - (b'mag ical \n tre vor\n', FAIL, b' tre vor\nmag ical \n'), - (b'@\n-\n_\n#\n', FAIL, b'#\n-\n@\n_\n'), - (b'extra\n\n\nwhitespace\n', FAIL, b'extra\nwhitespace\n'), - (b'whitespace\n\n\nextra\n', FAIL, b'extra\nwhitespace\n'), + (b'', [], FAIL, b'\n'), + (b'lonesome\n', [], PASS, b'lonesome\n'), + (b'missing_newline', [], FAIL, b'missing_newline\n'), + (b'newline\nmissing', [], FAIL, b'missing\nnewline\n'), + (b'missing\nnewline', [], FAIL, b'missing\nnewline\n'), + (b'alpha\nbeta\n', [], PASS, b'alpha\nbeta\n'), + (b'beta\nalpha\n', [], FAIL, b'alpha\nbeta\n'), + (b'C\nc\n', [], PASS, b'C\nc\n'), + (b'c\nC\n', [], FAIL, b'C\nc\n'), + (b'mag ical \n tre vor\n', [], FAIL, b' tre vor\nmag ical \n'), + (b'@\n-\n_\n#\n', [], FAIL, b'#\n-\n@\n_\n'), + (b'extra\n\n\nwhitespace\n', [], FAIL, b'extra\nwhitespace\n'), + (b'whitespace\n\n\nextra\n', [], FAIL, b'extra\nwhitespace\n'), + ( + b'fee\nFie\nFoe\nfum\n', + [], + FAIL, + b'Fie\nFoe\nfee\nfum\n', + ), + ( + b'Fie\nFoe\nfee\nfum\n', + [], + PASS, + b'Fie\nFoe\nfee\nfum\n', + ), + ( + b'fee\nFie\nFoe\nfum\n', + ['--ignore-case'], + PASS, + b'fee\nFie\nFoe\nfum\n', + ), + ( + b'Fie\nFoe\nfee\nfum\n', + ['--ignore-case'], + FAIL, + b'fee\nFie\nFoe\nfum\n', + ), ), ) -def test_integration(input_s, expected_retval, output, tmpdir): +def test_integration(input_s, argv, expected_retval, output, tmpdir): path = tmpdir.join('file.txt') path.write_binary(input_s) - output_retval = main([str(path)]) + output_retval = main([str(path)] + argv) assert path.read_binary() == output assert output_retval == expected_retval From 012bb0691f4e1615c11be5860d9e427523d42985 Mon Sep 17 00:00:00 2001 From: Marcus Shawcroft Date: Wed, 16 Sep 2020 06:26:11 +0100 Subject: [PATCH 120/334] Fix #518, provide --enforce-all option to check_added_large_files The --enforce-all option when provided ensures that all files passed on the command line are checked against the size limit. Default behaviour remains unchanged. --- README.md | 3 +++ pre_commit_hooks/check_added_large_files.py | 25 +++++++++++++++++---- tests/check_added_large_files_test.py | 23 +++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3552721f..a6b62abd 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,11 @@ Add this to your `.pre-commit-config.yaml` #### `check-added-large-files` Prevent giant files from being committed. - Specify what is "too large" with `args: ['--maxkb=123']` (default=500kB). + - Limits checked files to those indicated as staged for addition by git. - If `git-lfs` is installed, lfs files will be skipped (requires `git-lfs>=2.2.1`) + - `--enforce-all` - Check all listed files not just those staged for + addition. #### `check-ast` Simply check whether files parse as valid python. diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index 91f57544..cb646d7b 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -21,11 +21,20 @@ def lfs_files() -> Set[str]: return set(json.loads(lfs_ret)['files']) -def find_large_added_files(filenames: Sequence[str], maxkb: int) -> int: +def find_large_added_files( + filenames: Sequence[str], + maxkb: int, + *, + enforce_all: bool = False, +) -> int: # Find all added files that are also in the list of files pre-commit tells # us about retv = 0 - for filename in (added_files() & set(filenames)) - lfs_files(): + filenames_filtered = set(filenames) - lfs_files() + if not enforce_all: + filenames_filtered &= added_files() + + for filename in filenames_filtered: kb = int(math.ceil(os.stat(filename).st_size / 1024)) if kb > maxkb: print(f'{filename} ({kb} KB) exceeds {maxkb} KB.') @@ -40,13 +49,21 @@ def main(argv: Optional[Sequence[str]] = None) -> int: 'filenames', nargs='*', help='Filenames pre-commit believes are changed.', ) + parser.add_argument( + '--enforce-all', action='store_true', + help='Enforce all files are checked, not just staged files.', + ) parser.add_argument( '--maxkb', type=int, default=500, help='Maxmimum allowable KB for added files', ) - args = parser.parse_args(argv) - return find_large_added_files(args.filenames, args.maxkb) + + return find_large_added_files( + args.filenames, + args.maxkb, + enforce_all=args.enforce_all, + ) if __name__ == '__main__': diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index 40ffd24d..ff53b05b 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -40,6 +40,17 @@ def test_add_something_giant(temp_git_dir): assert find_large_added_files(['f.py'], 10) == 0 +def test_enforce_all(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.join('f.py').write('a' * 10000) + + # Should fail, when not staged with enforce_all + assert find_large_added_files(['f.py'], 0, enforce_all=True) == 1 + + # Should pass, when not staged without enforce_all + assert find_large_added_files(['f.py'], 0, enforce_all=False) == 0 + + def test_added_file_not_in_pre_commits_list(temp_git_dir): with temp_git_dir.as_cwd(): temp_git_dir.join('f.py').write("print('hello world')") @@ -97,3 +108,15 @@ def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover # Now move it and make sure the hook still succeeds cmd_output('git', 'mv', 'a.bin', 'b.bin') assert main(('--maxkb', '9', 'b.bin')) == 0 + + +@xfailif_no_gitlfs +def test_enforce_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover + with temp_git_dir.as_cwd(): + monkeypatch.setenv('HOME', str(temp_git_dir)) + cmd_output('git', 'lfs', 'install') + temp_git_dir.join('f.py').write('a' * 10000) + cmd_output('git', 'lfs', 'track', 'f.py') + cmd_output('git', 'add', '--', '.') + # With --enforce-all large files on git lfs should succeed + assert main(('--enforce-all', '--maxkb', '9', 'f.py')) == 0 From d18bd5b75f9b7d49a3c8c105cd95362a24ec6e31 Mon Sep 17 00:00:00 2001 From: Jeremiah Gowdy Date: Sun, 4 Oct 2020 18:45:54 -0700 Subject: [PATCH 121/334] Add new byte-order-marker checker/fixer --- .pre-commit-hooks.yaml | 10 ++++++-- README.md | 7 +++--- pre_commit_hooks/fix_byte_order_marker.py | 30 +++++++++++++++++++++++ setup.cfg | 1 + tests/fix_byte_order_marker_test.py | 13 ++++++++++ 5 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 pre_commit_hooks/fix_byte_order_marker.py create mode 100644 tests/fix_byte_order_marker_test.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 3e4dc9ea..a47f7339 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -17,8 +17,8 @@ language: python types: [python] - id: check-byte-order-marker - name: Check for byte-order marker - description: Forbid files which have a UTF-8 byte-order marker + name: 'check BOM - deprecated: use fix-byte-order-marker' + description: forbid files which have a UTF-8 byte-order marker entry: check-byte-order-marker language: python types: [text] @@ -131,6 +131,12 @@ entry: file-contents-sorter language: python files: '^$' +- id: fix-byte-order-marker + name: fix UTF-8 byte order marker + description: removes UTF-8 byte order marker + entry: fix-byte-order-marker + language: python + types: [text] - id: fix-encoding-pragma name: Fix python encoding pragma language: python diff --git a/README.md b/README.md index a6b62abd..18340bf7 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,6 @@ Require literal syntax when initializing empty or zero Python builtin types. - Ignore this requirement for specific builtin types with `--ignore=type1,type2,…`. - Forbid `dict` keyword syntax with `--no-allow-dict-kwargs`. -#### `check-byte-order-marker` -Forbid files which have a UTF-8 byte-order marker - #### `check-case-conflict` Check for files with names that would conflict on a case-insensitive filesystem like MacOS HFS+ or Windows FAT. @@ -102,6 +99,9 @@ This hook replaces double quoted strings with single quoted strings. #### `end-of-file-fixer` Makes sure files end in a newline and only a newline. +#### `fix-byte-order-marker` +removes UTF-8 byte order marker + #### `fix-encoding-pragma` Add `# -*- coding: utf-8 -*-` to the top of python files. - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) @@ -183,6 +183,7 @@ Trims trailing whitespace. [mirrors-autopep8](https://github.com/pre-commit/mirrors-autopep8) - `pyflakes`: instead use `flake8` - `flake8`: instead use [upstream flake8](https://gitlab.com/pycqa/flake8) +- `check-byte-order-marker`: instead use fix-byte-order-marker ### As a standalone package diff --git a/pre_commit_hooks/fix_byte_order_marker.py b/pre_commit_hooks/fix_byte_order_marker.py new file mode 100644 index 00000000..1ffe047d --- /dev/null +++ b/pre_commit_hooks/fix_byte_order_marker.py @@ -0,0 +1,30 @@ +import argparse +from typing import Optional +from typing import Sequence + + +def main(argv: Optional[Sequence[str]] = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument('filenames', nargs='*', help='Filenames to check') + args = parser.parse_args(argv) + + retv = 0 + + for filename in args.filenames: + with open(filename, 'rb') as f_b: + bts = f_b.read(3) + + if bts == b'\xef\xbb\xbf': + with open(filename, newline='', encoding='utf-8-sig') as f: + contents = f.read() + with open(filename, 'w', newline='', encoding='utf-8') as f: + f.write(contents) + + print(f'{filename}: removed byte-order marker') + retv = 1 + + return retv + + +if __name__ == '__main__': + exit(main()) diff --git a/setup.cfg b/setup.cfg index 47b8bb6d..c8677f56 100644 --- a/setup.cfg +++ b/setup.cfg @@ -48,6 +48,7 @@ console_scripts = double-quote-string-fixer = pre_commit_hooks.string_fixer:main end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:main file-contents-sorter = pre_commit_hooks.file_contents_sorter:main + fix-byte-order-marker = pre_commit_hooks.fix_byte_order_marker:main fix-encoding-pragma = pre_commit_hooks.fix_encoding_pragma:main forbid-new-submodules = pre_commit_hooks.forbid_new_submodules:main mixed-line-ending = pre_commit_hooks.mixed_line_ending:main diff --git a/tests/fix_byte_order_marker_test.py b/tests/fix_byte_order_marker_test.py new file mode 100644 index 00000000..da150e37 --- /dev/null +++ b/tests/fix_byte_order_marker_test.py @@ -0,0 +1,13 @@ +from pre_commit_hooks import fix_byte_order_marker + + +def test_failure(tmpdir): + f = tmpdir.join('f.txt') + f.write_text('ohai', encoding='utf-8-sig') + assert fix_byte_order_marker.main((str(f),)) == 1 + + +def test_success(tmpdir): + f = tmpdir.join('f.txt') + f.write_text('ohai', encoding='utf-8') + assert fix_byte_order_marker.main((str(f),)) == 0 From 9136088a246768144165fcc3ecc3d31bb686920a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 20 Oct 2020 10:17:01 -0700 Subject: [PATCH 122/334] v3.3.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 17 +++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b4614a74..d7885c61 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v3.3.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aa7441b..08966ece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +3.3.0 - 2020-10-20 +================== + +### Features +- `file-contents-sorter`: add `--ignore-case` option for case-insensitive + sorting + - #514 PR by @Julian. +- `check-added-large-files`: add `--enforce-all` option to check non-added + files as well + - #519 PR by @mshawcroft. + - #518 issue by @mshawcroft. +- `fix-byte-order-marker`: new hook which fixes UTF-8 byte-order marker. + - #522 PR by @jgowdy. + +### Deprecations +- `check-byte-order-marker` is now deprecated for `fix-byte-order-marker` + 3.2.0 - 2020-07-30 ================== diff --git a/README.md b/README.md index 18340bf7..3fe52f02 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 # Use the ref you want to point at + rev: v3.3.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index c8677f56..ab80bd60 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 3.2.0 +version = 3.3.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 7e393476bd1dadea277e45e25702b56f142f8fca Mon Sep 17 00:00:00 2001 From: Daniel Hoherd Date: Sat, 24 Oct 2020 21:05:40 -0700 Subject: [PATCH 123/334] Add --unique arg to file-contents-sorter --- pre_commit_hooks/file_contents_sorter.py | 20 ++++++++++++---- tests/file_contents_sorter_test.py | 30 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 4c1c7479..ebbcd206 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -13,6 +13,7 @@ from typing import Any from typing import Callable from typing import IO +from typing import Iterable from typing import Optional from typing import Sequence @@ -23,12 +24,16 @@ def sort_file_contents( f: IO[bytes], key: Optional[Callable[[bytes], Any]], + *, + unique: bool = False, ) -> int: before = list(f) - after = sorted( - (line.strip(b'\n\r') for line in before if line.strip()), - key=key, + lines: Iterable[bytes] = ( + line.rstrip(b'\n\r') for line in before if line.strip() ) + if unique: + lines = set(lines) + after = sorted(lines, key=key) before_string = b''.join(before) after_string = b'\n'.join(after) + b'\n' @@ -52,13 +57,20 @@ def main(argv: Optional[Sequence[str]] = None) -> int: default=None, help='fold lower case to upper case characters', ) + parser.add_argument( + '--unique', + action='store_true', + help='ensure each line is unique', + ) args = parser.parse_args(argv) retv = PASS for arg in args.filenames: with open(arg, 'rb+') as file_obj: - ret_for_file = sort_file_contents(file_obj, key=args.ignore_case) + ret_for_file = sort_file_contents( + file_obj, key=args.ignore_case, unique=args.unique, + ) if ret_for_file: print(f'Sorting {arg}') diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py index 9ebb021a..15f11342 100644 --- a/tests/file_contents_sorter_test.py +++ b/tests/file_contents_sorter_test.py @@ -45,6 +45,36 @@ FAIL, b'fee\nFie\nFoe\nfum\n', ), + ( + b'Fie\nFoe\nfee\nfee\nfum\n', + ['--ignore-case'], + FAIL, + b'fee\nfee\nFie\nFoe\nfum\n', + ), + ( + b'Fie\nFoe\nfee\nfum\n', + ['--unique'], + PASS, + b'Fie\nFoe\nfee\nfum\n', + ), + ( + b'Fie\nFie\nFoe\nfee\nfum\n', + ['--unique'], + FAIL, + b'Fie\nFoe\nfee\nfum\n', + ), + ( + b'fee\nFie\nFoe\nfum\n', + ['--unique', '--ignore-case'], + PASS, + b'fee\nFie\nFoe\nfum\n', + ), + ( + b'fee\nfee\nFie\nFoe\nfum\n', + ['--unique', '--ignore-case'], + FAIL, + b'fee\nFie\nFoe\nfum\n', + ), ), ) def test_integration(input_s, argv, expected_retval, output, tmpdir): From 7d9c32e9a0608a2b237c958e5cd31f258d381d0c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 29 Oct 2020 11:38:19 -0700 Subject: [PATCH 124/334] use pre-commit.ci --- README.md | 1 + azure-pipelines.yml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3fe52f02..24d716fd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [![Build Status](https://asottile.visualstudio.com/asottile/_apis/build/status/pre-commit.pre-commit-hooks?branchName=master)](https://asottile.visualstudio.com/asottile/_build/latest?definitionId=17&branchName=master) [![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/asottile/asottile/17/master.svg)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=17&branchName=master) +[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pre-commit/pre-commit-hooks/master.svg)](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit-hooks/master) pre-commit-hooks ================ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index dc3a57a9..c1ef4f4c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,7 +13,6 @@ resources: ref: refs/tags/v1.0.0 jobs: -- template: job--pre-commit.yml@asottile - template: job--python-tox.yml@asottile parameters: toxenvs: [py38] From 29fc56c40c82e04e634331b3e6dc9ec21ce6ee4b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 17:04:49 +0000 Subject: [PATCH 125/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d7885c61..4b4763e8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,25 +13,25 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.0 + rev: 3.8.4 hooks: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.5.2 + rev: v1.5.4 hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v2.4.0 + rev: v2.8.2 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports - rev: v2.3.0 + rev: v2.3.6 hooks: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.4.1 + rev: v2.7.4 hooks: - id: pyupgrade args: [--py36-plus] @@ -41,10 +41,10 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.9.0 + rev: v1.15.1 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.770 + rev: v0.790 hooks: - id: mypy From e90998353b4f1633264860a69ebbeed6f788c3af Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 17:05:14 +0000 Subject: [PATCH 126/334] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index ab80bd60..3c401fc9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,6 +16,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy From 64d3fbd5cfeba19954e04c32422967ee446e794d Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 16 Nov 2020 10:41:32 -0800 Subject: [PATCH 127/334] fix mypy by correcting the __lt__ annotation --- pre_commit_hooks/requirements_txt_fixer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 78103a14..24126331 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -36,7 +36,7 @@ def name(self) -> bytes: return name[:m.start()] - def __lt__(self, requirement: 'Requirement') -> int: + 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 From 1f8151aeebb24311c2d08de2c93045a5f8bfca5c Mon Sep 17 00:00:00 2001 From: Youngmin Koo Date: Tue, 17 Nov 2020 02:33:47 +0900 Subject: [PATCH 128/334] Add --additional-github-domain to check-vcs-permalinks --- README.md | 4 +++ pre_commit_hooks/check_vcs_permalinks.py | 35 +++++++++++++++++------- tests/check_vcs_permalinks_test.py | 6 ++-- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 24d716fd..2a762680 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,10 @@ Attempts to load all TOML files to verify syntax. #### `check-vcs-permalinks` Ensures that links to vcs websites are permalinks. + - `--additional-github-domain DOMAIN` - Add check for specified domain. + Can be repeated multiple times. for example, if your company uses + GitHub Enterprise you may use something like + `--additional-github-domain github.example.com` #### `check-xml` Attempts to load all xml files to verify syntax. diff --git a/pre_commit_hooks/check_vcs_permalinks.py b/pre_commit_hooks/check_vcs_permalinks.py index bf698e11..a30277ce 100644 --- a/pre_commit_hooks/check_vcs_permalinks.py +++ b/pre_commit_hooks/check_vcs_permalinks.py @@ -1,35 +1,50 @@ import argparse import re import sys +from typing import List from typing import Optional +from typing import Pattern from typing import Sequence -GITHUB_NON_PERMALINK = re.compile( - br'https://github.com/[^/ ]+/[^/ ]+/blob/master/[^# ]+#L\d+', -) +def _get_pattern(domain: str) -> Pattern[bytes]: + regex = rf'https://{domain}/[^/ ]+/[^/ ]+/blob/master/[^# ]+#L\d+' + return re.compile(regex.encode()) -def _check_filename(filename: str) -> 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): - if GITHUB_NON_PERMALINK.search(line): - sys.stdout.write(f'{filename}:{i}:') - sys.stdout.flush() - sys.stdout.buffer.write(line) - retv = 1 + for pattern in patterns: + if pattern.search(line): + sys.stdout.write(f'{filename}:{i}:') + sys.stdout.flush() + sys.stdout.buffer.write(line) + retv = 1 return retv def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') + parser.add_argument( + '--additional-github-domain', + dest='additional_github_domains', + action='append', + default=['github.com'], + ) args = parser.parse_args(argv) + patterns = [ + _get_pattern(domain) + for domain in args.additional_github_domains + ] + retv = 0 + for filename in args.filenames: - retv |= _check_filename(filename) + retv |= _check_filename(filename, patterns) if retv: print() diff --git a/tests/check_vcs_permalinks_test.py b/tests/check_vcs_permalinks_test.py index 19b1c355..7d5f86c2 100644 --- a/tests/check_vcs_permalinks_test.py +++ b/tests/check_vcs_permalinks_test.py @@ -22,13 +22,15 @@ def test_passing(tmpdir): def test_failing(tmpdir, capsys): with tmpdir.as_cwd(): tmpdir.join('f.txt').write_binary( - b'https://github.com/asottile/test/blob/master/foo#L1\n', + b'https://github.com/asottile/test/blob/master/foo#L1\n' + b'https://example.com/asottile/test/blob/master/foo#L1\n', ) - assert main(('f.txt',)) + assert main(('f.txt', '--additional-github-domain', 'example.com')) out, _ = capsys.readouterr() assert out == ( 'f.txt:1:https://github.com/asottile/test/blob/master/foo#L1\n' + 'f.txt:2:https://example.com/asottile/test/blob/master/foo#L1\n' '\n' 'Non-permanent github link detected.\n' 'On any page on github press [y] to load a permalink.\n' From 1e87d59a2d02c17ef7c305e4c8e883b841eb1d8b Mon Sep 17 00:00:00 2001 From: Mikhail Khvoinitsky Date: Sun, 2 Aug 2020 21:25:07 +0300 Subject: [PATCH 129/334] New hook 'destroyed-symlinks' to detect symlinks which are changed to regular files with a content of a path which that symlink was pointing to; move zsplit to util --- .pre-commit-hooks.yaml | 6 ++ README.md | 6 ++ .../check_executables_have_shebangs.py | 9 +- pre_commit_hooks/destroyed_symlinks.py | 96 +++++++++++++++++++ pre_commit_hooks/util.py | 9 ++ setup.cfg | 1 + tests/check_executables_have_shebangs_test.py | 10 -- tests/destroyed_symlinks_test.py | 74 ++++++++++++++ tests/util_test.py | 11 +++ 9 files changed, 204 insertions(+), 18 deletions(-) create mode 100755 pre_commit_hooks/destroyed_symlinks.py create mode 100644 tests/destroyed_symlinks_test.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index a47f7339..fa617b97 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -100,6 +100,12 @@ entry: debug-statement-hook language: python types: [python] +- id: destroyed-symlinks + name: Detect Destroyed Symlinks + description: Detects symlinks which are changed to regular files with a content of a path which that symlink was pointing to. + entry: destroyed-symlinks + language: python + types: [file] - id: detect-aws-credentials name: Detect AWS Credentials description: Detects *your* aws credentials from the aws cli credentials file diff --git a/README.md b/README.md index 2a762680..3a87e9cf 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,12 @@ Attempts to load all yaml files to verify syntax. #### `debug-statements` Check for debugger imports and py37+ `breakpoint()` calls in python source. +#### `destroyed-symlinks` +Detects symlinks which are changed to regular files with a content of a path +which that symlink was pointing to. +This usually happens on Windows when a user clones a repository that has +symlinks but they do not have the permission to create symlinks. + #### `detect-aws-credentials` Checks for the existence of AWS secrets that you have set up with the AWS CLI. The following arguments are available: diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index a02d2a9c..2d2bd7df 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -8,18 +8,11 @@ from typing import Set from pre_commit_hooks.util import cmd_output +from pre_commit_hooks.util import zsplit EXECUTABLE_VALUES = frozenset(('1', '3', '5', '7')) -def zsplit(s: str) -> List[str]: - s = s.strip('\0') - if s: - return s.split('\0') - else: - return [] - - def check_executables(paths: List[str]) -> int: if sys.platform == 'win32': # pragma: win32 cover return _check_git_filemode(paths) diff --git a/pre_commit_hooks/destroyed_symlinks.py b/pre_commit_hooks/destroyed_symlinks.py new file mode 100755 index 00000000..cfaf4e53 --- /dev/null +++ b/pre_commit_hooks/destroyed_symlinks.py @@ -0,0 +1,96 @@ +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 +from pre_commit_hooks.util import zsplit + +ORDINARY_CHANGED_ENTRIES_MARKER = '1' +PERMS_LINK = '120000' +PERMS_NONEXIST = '000000' + + +def find_destroyed_symlinks(files: Sequence[str]) -> List[str]: + destroyed_links: List[str] = [] + if not files: + return destroyed_links + for line in zsplit( + cmd_output('git', 'status', '--porcelain=v2', '-z', '--', *files), + ): + splitted = line.split(' ') + if splitted and splitted[0] == ORDINARY_CHANGED_ENTRIES_MARKER: + # https://git-scm.com/docs/git-status#_changed_tracked_entries + ( + _, _, _, + mode_HEAD, + mode_index, + _, + hash_HEAD, + hash_index, + *path_splitted, + ) = splitted + path = ' '.join(path_splitted) + if ( + mode_HEAD == PERMS_LINK and + mode_index != PERMS_LINK and + mode_index != PERMS_NONEXIST + ): + if hash_HEAD == hash_index: + # if old and new hashes are equal, it's not needed to check + # anything more, we've found a destroyed symlink for sure + destroyed_links.append(path) + else: + # if old and new hashes are *not* equal, it doesn't mean + # that everything is OK - new file may be altered + # by something like trailing-whitespace and/or + # mixed-line-ending hooks so we need to go deeper + SIZE_CMD = ('git', 'cat-file', '-s') + size_index = int(cmd_output(*SIZE_CMD, hash_index).strip()) + size_HEAD = int(cmd_output(*SIZE_CMD, hash_HEAD).strip()) + + # in the worst case new file may have CRLF added + # so check content only if new file is bigger + # not more than 2 bytes compared to the old one + if size_index <= size_HEAD + 2: + head_content = subprocess.check_output( + ('git', 'cat-file', '-p', hash_HEAD), + ).rstrip() + index_content = subprocess.check_output( + ('git', 'cat-file', '-p', hash_index), + ).rstrip() + if head_content == index_content: + destroyed_links.append(path) + return destroyed_links + + +def main(argv: Optional[Sequence[str]] = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument('filenames', nargs='*', help='Filenames to check.') + args = parser.parse_args(argv) + destroyed_links = find_destroyed_symlinks(files=args.filenames) + if destroyed_links: + print('Destroyed symlinks:') + for destroyed_link in destroyed_links: + print(f'- {destroyed_link}') + print('You should unstage affected files:') + print( + '\tgit reset HEAD -- {}'.format( + ' '.join(shlex.quote(link) for link in destroyed_links), + ), + ) + print( + 'And retry commit. As a long term solution ' + 'you may try to explicitly tell git that your ' + 'environment does not support symlinks:', + ) + print('\tgit config core.symlinks false') + return 1 + else: + return 0 + + +if __name__ == '__main__': + exit(main()) diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py index e04b0150..402e33e6 100644 --- a/pre_commit_hooks/util.py +++ b/pre_commit_hooks/util.py @@ -1,5 +1,6 @@ import subprocess from typing import Any +from typing import List from typing import Optional from typing import Set @@ -22,3 +23,11 @@ def cmd_output(*cmd: str, retcode: Optional[int] = 0, **kwargs: Any) -> str: if retcode is not None and proc.returncode != retcode: raise CalledProcessError(cmd, retcode, proc.returncode, stdout, stderr) return stdout + + +def zsplit(s: str) -> List[str]: + s = s.strip('\0') + if s: + return s.split('\0') + else: + return [] diff --git a/setup.cfg b/setup.cfg index 3c401fc9..e2cad1ab 100644 --- a/setup.cfg +++ b/setup.cfg @@ -44,6 +44,7 @@ console_scripts = check-xml = pre_commit_hooks.check_xml:main check-yaml = pre_commit_hooks.check_yaml:main debug-statement-hook = pre_commit_hooks.debug_statement_hook:main + destroyed-symlinks = pre_commit_hooks.destroyed_symlinks:main detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main detect-private-key = pre_commit_hooks.detect_private_key:main double-quote-string-fixer = pre_commit_hooks.string_fixer:main diff --git a/tests/check_executables_have_shebangs_test.py b/tests/check_executables_have_shebangs_test.py index 7046081f..5703eded 100644 --- a/tests/check_executables_have_shebangs_test.py +++ b/tests/check_executables_have_shebangs_test.py @@ -102,16 +102,6 @@ def test_check_git_filemode_failing(tmpdir): assert check_executables_have_shebangs._check_git_filemode(files) == 1 -@pytest.mark.parametrize('out', ('\0f1\0f2\0', '\0f1\0f2', 'f1\0f2\0')) -def test_check_zsplits_correctly(out): - assert check_executables_have_shebangs.zsplit(out) == ['f1', 'f2'] - - -@pytest.mark.parametrize('out', ('\0\0', '\0', '')) -def test_check_zsplit_returns_empty(out): - assert check_executables_have_shebangs.zsplit(out) == [] - - @pytest.mark.parametrize( ('content', 'mode', 'expected'), ( diff --git a/tests/destroyed_symlinks_test.py b/tests/destroyed_symlinks_test.py new file mode 100644 index 00000000..d2c90310 --- /dev/null +++ b/tests/destroyed_symlinks_test.py @@ -0,0 +1,74 @@ +import os +import subprocess + +import pytest + +from pre_commit_hooks.destroyed_symlinks import find_destroyed_symlinks +from pre_commit_hooks.destroyed_symlinks import main + +TEST_SYMLINK = 'test_symlink' +TEST_SYMLINK_TARGET = '/doesnt/really/matters' +TEST_FILE = 'test_file' +TEST_FILE_RENAMED = f'{TEST_FILE}_renamed' + + +@pytest.fixture +def repo_with_destroyed_symlink(tmpdir): + source_repo = tmpdir.join('src') + os.makedirs(source_repo, exist_ok=True) + test_repo = tmpdir.join('test') + with source_repo.as_cwd(): + subprocess.check_call(('git', 'init')) + os.symlink(TEST_SYMLINK_TARGET, TEST_SYMLINK) + with open(TEST_FILE, 'w') as f: + print('some random content', file=f) + subprocess.check_call(('git', 'add', '.')) + subprocess.check_call( + ('git', 'commit', '--no-gpg-sign', '-m', 'initial'), + ) + assert b'120000 ' in subprocess.check_output( + ('git', 'cat-file', '-p', 'HEAD^{tree}'), + ) + subprocess.check_call( + ('git', '-c', 'core.symlinks=false', 'clone', source_repo, test_repo), + ) + with test_repo.as_cwd(): + subprocess.check_call( + ('git', 'config', '--local', 'core.symlinks', 'true'), + ) + subprocess.check_call(('git', 'mv', TEST_FILE, TEST_FILE_RENAMED)) + assert not os.path.islink(test_repo.join(TEST_SYMLINK)) + yield test_repo + + +def test_find_destroyed_symlinks(repo_with_destroyed_symlink): + with repo_with_destroyed_symlink.as_cwd(): + assert find_destroyed_symlinks([]) == [] + assert main([]) == 0 + + subprocess.check_call(('git', 'add', TEST_SYMLINK)) + assert find_destroyed_symlinks([TEST_SYMLINK]) == [TEST_SYMLINK] + assert find_destroyed_symlinks([]) == [] + assert main([]) == 0 + assert find_destroyed_symlinks([TEST_FILE_RENAMED, TEST_FILE]) == [] + ALL_STAGED = [TEST_SYMLINK, TEST_FILE_RENAMED] + assert find_destroyed_symlinks(ALL_STAGED) == [TEST_SYMLINK] + assert main(ALL_STAGED) != 0 + + with open(TEST_SYMLINK, 'a') as f: + print(file=f) # add trailing newline + subprocess.check_call(['git', 'add', TEST_SYMLINK]) + assert find_destroyed_symlinks(ALL_STAGED) == [TEST_SYMLINK] + assert main(ALL_STAGED) != 0 + + with open(TEST_SYMLINK, 'w') as f: + print('0' * len(TEST_SYMLINK_TARGET), file=f) + subprocess.check_call(('git', 'add', TEST_SYMLINK)) + assert find_destroyed_symlinks(ALL_STAGED) == [] + assert main(ALL_STAGED) == 0 + + with open(TEST_SYMLINK, 'w') as f: + print('0' * (len(TEST_SYMLINK_TARGET) + 3), file=f) + subprocess.check_call(('git', 'add', TEST_SYMLINK)) + assert find_destroyed_symlinks(ALL_STAGED) == [] + assert main(ALL_STAGED) == 0 diff --git a/tests/util_test.py b/tests/util_test.py index b42ee6f9..7f488161 100644 --- a/tests/util_test.py +++ b/tests/util_test.py @@ -2,6 +2,7 @@ from pre_commit_hooks.util import CalledProcessError from pre_commit_hooks.util import cmd_output +from pre_commit_hooks.util import zsplit def test_raises_on_error(): @@ -12,3 +13,13 @@ def test_raises_on_error(): def test_output(): ret = cmd_output('sh', '-c', 'echo hi') assert ret == 'hi\n' + + +@pytest.mark.parametrize('out', ('\0f1\0f2\0', '\0f1\0f2', 'f1\0f2\0')) +def test_check_zsplits_str_correctly(out): + assert zsplit(out) == ['f1', 'f2'] + + +@pytest.mark.parametrize('out', ('\0\0', '\0', '')) +def test_check_zsplit_returns_empty(out): + assert zsplit(out) == [] From e3f0f5cec21b308d8553c32032e3c33e1ab412df Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 19 Nov 2020 17:13:08 -0800 Subject: [PATCH 130/334] Add link to GitHub Sponsors + Open Collective at the time of writing I am currently unemployed. I'd love to make open source a full time career. if you or your company is deriving value from this free software, please consider [sponsoring] or [supporting]. [sponsoring]: https://github.com/sponsors/asottile [supporting]: https://opencollective.com/pre-commit Committed via https://github.com/asottile/all-repos --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..9408e44d --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: asottile +open_collective: pre-commit From 07699f5dae3255c9d62795454b47db5ecf40c234 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Nov 2020 16:40:39 +0000 Subject: [PATCH 131/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b4763e8..bfa2a022 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v2.8.2 + rev: v2.9.0 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports From 1c39c70d88e734a692f0c81c405fd305c491ba22 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Nov 2020 16:30:53 +0000 Subject: [PATCH 132/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bfa2a022..426343d0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v2.9.0 + rev: v2.9.2 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports From c4f18bab1a96adafc7cb91c79c1cdeab2b1f3cfd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 16:35:17 +0000 Subject: [PATCH 133/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 426343d0..0549f4eb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/pre-commit/pre-commit - rev: v2.9.2 + rev: v2.9.3 hooks: - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports From 6e2418c5521b7d606e72914dced3253f9ace1205 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 15 Dec 2020 13:46:40 -0800 Subject: [PATCH 134/334] v3.4.0 --- .pre-commit-config.yaml | 6 +----- CHANGELOG.md | 12 ++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0549f4eb..3553642d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.3.0 + rev: v3.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -21,10 +21,6 @@ repos: rev: v1.5.4 hooks: - id: autopep8 -- repo: https://github.com/pre-commit/pre-commit - rev: v2.9.3 - hooks: - - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports rev: v2.3.6 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index 08966ece..5de3576e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +3.4.0 - 2020-12-15 +================== + +### Features +- `file-contents-sorter`: Add `--unique` argument + - #524 PR by @danielhoherd. +- `check-vcs-permalinks`: Add `--additional-github-domain` option + - #530 PR by @youngminz. +- New hook: `destroyed-symlinks` to detect unintentional symlink-breakages on + windows. + - #511 PR by @m-khvoinitsky. + 3.3.0 - 2020-10-20 ================== diff --git a/README.md b/README.md index 3a87e9cf..f66d2657 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.3.0 # Use the ref you want to point at + rev: v3.4.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index e2cad1ab..31c9c84b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 3.3.0 +version = 3.4.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 19be55750596cea028b5fb8bf5888699815bc634 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 16:44:37 +0000 Subject: [PATCH 135/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3553642d..4c710197 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.15.1 + rev: v1.16.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy From 208220479130f162e472b723c1ed4d6a970c13b3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Jan 2021 16:43:45 +0000 Subject: [PATCH 136/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4c710197..62f6bfac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.0.1 + rev: v2.0.2 hooks: - id: add-trailing-comma args: [--py36-plus] From dae0cbd2fa5d139a529d0d1514b0883f131d1e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 8 Jan 2021 16:22:33 +0200 Subject: [PATCH 137/334] check_executables_have_shebangs: avoid unneeded shebang reads on win32 --- pre_commit_hooks/check_executables_have_shebangs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index 2d2bd7df..19f7ed27 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -34,8 +34,7 @@ def _check_git_filemode(paths: Sequence[str]) -> int: tagmode = metadata.split(' ', 1)[0] is_executable = any(b in EXECUTABLE_VALUES for b in tagmode[-3:]) - has_shebang = _check_has_shebang(path) - if is_executable and not has_shebang: + if is_executable and not _check_has_shebang(path): _message(path) seen.add(path) From 28b2c8e431cbb1a58a347d339fc57b28c89e6794 Mon Sep 17 00:00:00 2001 From: Viacheslav Greshilov Date: Sun, 17 Jan 2021 21:15:05 +0200 Subject: [PATCH 138/334] requirements-txt-fixer now supports indents before comments --- pre_commit_hooks/requirements_txt_fixer.py | 2 +- tests/requirements_txt_fixer_test.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 24126331..351e5b15 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -95,7 +95,7 @@ def fix_requirements(f: IO[bytes]) -> int: requirement.value = b'\n' else: requirement.comments.append(line) - elif line.startswith(b'#') or line.strip() == b'': + elif line.lstrip().startswith(b'#') or line.strip() == b'': requirement.comments.append(line) else: requirement.append_value(line) diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index f4f679da..e3c6ed50 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -30,6 +30,16 @@ ), (b'#comment\n\nfoo\nbar\n', FAIL, b'#comment\n\nbar\nfoo\n'), (b'#comment\n\nbar\nfoo\n', PASS, b'#comment\n\nbar\nfoo\n'), + ( + b'foo\n\t#comment with indent\nbar\n', + FAIL, + b'\t#comment with indent\nbar\nfoo\n', + ), + ( + b'bar\n\t#comment with indent\nfoo\n', + PASS, + b'bar\n\t#comment with indent\nfoo\n', + ), (b'\nfoo\nbar\n', FAIL, b'bar\n\nfoo\n'), (b'\nbar\nfoo\n', PASS, b'\nbar\nfoo\n'), ( From a3a8d29b14ee24a42ad8efa6b2da70fd3a55a4ed Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Jan 2021 16:39:55 +0000 Subject: [PATCH 139/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62f6bfac..50ece945 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.0.2 + rev: v2.1.0 hooks: - id: add-trailing-comma args: [--py36-plus] @@ -41,6 +41,6 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.790 + rev: v0.800 hooks: - id: mypy From 81226d2cf42a080437c7ac5f95a97b57262eaec7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 16:48:14 +0000 Subject: [PATCH 140/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50ece945..4160b05b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.7.4 + rev: v2.9.0 hooks: - id: pyupgrade args: [--py36-plus] From aaa5981ebd518950750da85d67f85b5eb0bfe423 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:49:38 +0000 Subject: [PATCH 141/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4160b05b..c5a17381 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,12 +22,12 @@ repos: hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports - rev: v2.3.6 + rev: v2.4.0 hooks: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.9.0 + rev: v2.10.0 hooks: - id: pyupgrade args: [--py36-plus] From fe374517197c3db0f1e0c73098246d7f26da09ad Mon Sep 17 00:00:00 2001 From: Aditya Khursale Date: Wed, 17 Feb 2021 02:08:57 +0530 Subject: [PATCH 142/334] Report duplicate keys in check_json Raise ValueError and return 1 if json contains duplicate keys --- pre_commit_hooks/check_json.py | 18 +++++++++++++++++- testing/resources/duplicate_key_json.json | 4 ++++ tests/check_json_test.py | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 testing/resources/duplicate_key_json.json diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py index 6026270c..db589d01 100644 --- a/pre_commit_hooks/check_json.py +++ b/pre_commit_hooks/check_json.py @@ -1,7 +1,23 @@ 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]: + d = {} + for key, val in ordered_pairs: + if key in d: + raise ValueError(f'Duplicate key: {key}') + else: + d[key] = val + return d def main(argv: Optional[Sequence[str]] = None) -> int: @@ -13,7 +29,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: for filename in args.filenames: with open(filename, 'rb') as f: try: - json.load(f) + json.load(f, object_pairs_hook=raise_duplicate_keys) except ValueError as exc: print(f'{filename}: Failed to json decode ({exc})') retval = 1 diff --git a/testing/resources/duplicate_key_json.json b/testing/resources/duplicate_key_json.json new file mode 100644 index 00000000..8a432623 --- /dev/null +++ b/testing/resources/duplicate_key_json.json @@ -0,0 +1,4 @@ +{ + "hello": "world", + "hello": "planet" +} diff --git a/tests/check_json_test.py b/tests/check_json_test.py index c63dc4c8..e010faaa 100644 --- a/tests/check_json_test.py +++ b/tests/check_json_test.py @@ -9,6 +9,7 @@ ('bad_json.notjson', 1), ('bad_json_latin1.nonjson', 1), ('ok_json.json', 0), + ('duplicate_key_json.json', 1), ), ) def test_main(capsys, filename, expected_retval): From d90e97da2991e582d94cffed2e3796b184f8b4ed Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Feb 2021 17:03:23 +0000 Subject: [PATCH 143/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c5a17381..f18c1549 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,6 +41,6 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.800 + rev: v0.812 hooks: - id: mypy From 3abbd4785ccb2614b84012d5a6f1e2a98d52a7de Mon Sep 17 00:00:00 2001 From: Nicholas Devenish Date: Thu, 4 Mar 2021 13:41:04 +0000 Subject: [PATCH 144/334] no-commit-to-branch: Default to both master and main --- README.md | 2 +- pre_commit_hooks/no_commit_to_branch.py | 2 +- tests/no_commit_to_branch_test.py | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f66d2657..bf36ecf1 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ Assert that files in tests/ end in `_test.py`. #### `no-commit-to-branch` Protect specific branches from direct checkins. - Use `args: [--branch, staging, --branch, master]` to set the branch. - `master` is the default if no branch argument is set. + Both `master` and `main` are protected by default if no branch argument is set. - `-b` / `--branch` may be specified multiple times to protect multiple branches. - `-p` / `--pattern` can be used to protect branches that match a supplied regex diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index fb1506f9..49ffecf7 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -38,7 +38,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: ) args = parser.parse_args(argv) - protected = frozenset(args.branch or ('master',)) + protected = frozenset(args.branch or ('master', 'main')) patterns = frozenset(args.pattern or ()) return int(is_on_branch(protected, patterns)) diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py index 72b32e64..610e660e 100644 --- a/tests/no_commit_to_branch_test.py +++ b/tests/no_commit_to_branch_test.py @@ -67,3 +67,10 @@ def test_not_on_a_branch(temp_git_dir): cmd_output('git', 'checkout', head) # we're not on a branch! assert main(()) == 0 + + +@pytest.mark.parametrize('branch_name', ('master', 'main')) +def test_default_branch_names(temp_git_dir, branch_name): + with temp_git_dir.as_cwd(): + cmd_output('git', 'checkout', '-b', branch_name) + assert main(()) == 1 From 4dcbacbeb0947571db6b8977d7e6521c08294c36 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 17:00:31 +0000 Subject: [PATCH 145/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f18c1549..9552f02c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,12 +13,12 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + rev: 3.9.0 hooks: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.5.4 + rev: v1.5.5 hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports @@ -37,7 +37,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.16.0 + rev: v1.17.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy From c144e2b5b1aca42e5d22f84b80a34fd655e2f3f4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 17:01:52 +0000 Subject: [PATCH 146/334] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- setup.cfg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index 31c9c84b..631faabb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,6 +27,11 @@ install_requires = toml python_requires = >=3.6.1 +[options.packages.find] +exclude = + tests* + testing* + [options.entry_points] console_scripts = check-added-large-files = pre_commit_hooks.check_added_large_files:main @@ -62,11 +67,6 @@ console_scripts = sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main -[options.packages.find] -exclude = - tests* - testing* - [bdist_wheel] universal = True From 1de4fe6b42b7a4005b6723b4c5b87b4c17f8f4eb Mon Sep 17 00:00:00 2001 From: jack1142 <6032823+jack1142@users.noreply.github.com> Date: Sun, 14 Mar 2021 18:21:48 +0100 Subject: [PATCH 147/334] Update `pretty-format-json` to write to stdout with utf-8 encoding --- pre_commit_hooks/pretty_format_json.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 25827dc4..61b01698 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -1,5 +1,6 @@ import argparse import json +import sys from difflib import unified_diff from typing import List from typing import Mapping @@ -111,17 +112,6 @@ def main(argv: Optional[Sequence[str]] = None) -> int: contents, args.indent, ensure_ascii=not args.no_ensure_ascii, sort_keys=not args.no_sort_keys, top_keys=args.top_keys, ) - - if contents != pretty_contents: - if args.autofix: - _autofix(json_file, pretty_contents) - else: - print( - get_diff(contents, pretty_contents, json_file), - end='', - ) - - status = 1 except ValueError: print( f'Input File {json_file} is not a valid JSON, consider using ' @@ -129,6 +119,15 @@ def main(argv: Optional[Sequence[str]] = None) -> int: ) return 1 + if contents != pretty_contents: + if args.autofix: + _autofix(json_file, pretty_contents) + else: + diff_output = get_diff(contents, pretty_contents, json_file) + sys.stdout.buffer.write(diff_output.encode()) + + status = 1 + return status From 1cfedf373efc77c88f83f4f63c2bd3f50197ad1e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 17:03:46 +0000 Subject: [PATCH 148/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9552f02c..bea0d9e0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.5.5 + rev: v1.5.6 hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.10.0 + rev: v2.11.0 hooks: - id: pyupgrade args: [--py36-plus] From f681234a0e457afc6c4f2774d646dd6454d655a0 Mon Sep 17 00:00:00 2001 From: Krystian Chmura Date: Fri, 19 Mar 2021 00:59:31 +0100 Subject: [PATCH 149/334] check also directories in check_case_conflict fix #70 --- pre_commit_hooks/check_case_conflict.py | 15 +++++++ tests/check_case_conflict_test.py | 60 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py index 6b8ba82f..024c1c3c 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -1,5 +1,7 @@ import argparse +import os.path from typing import Iterable +from typing import Iterator from typing import Optional from typing import Sequence from typing import Set @@ -12,9 +14,22 @@ def lower_set(iterable: Iterable[str]) -> Set[str]: return {x.lower() for x in iterable} +def parents(file: str) -> Iterator[str]: + file = os.path.dirname(file) + while file: + yield file + file = os.path.dirname(file) + + +def directories_for(files: Set[str]) -> Set[str]: + return {parent for file in files for parent in parents(file)} + + def find_conflicting_filenames(filenames: Sequence[str]) -> int: repo_files = set(cmd_output('git', 'ls-files').splitlines()) + repo_files |= directories_for(repo_files) relevant_files = set(filenames) | added_files() + relevant_files |= directories_for(relevant_files) repo_files -= relevant_files retv = 0 diff --git a/tests/check_case_conflict_test.py b/tests/check_case_conflict_test.py index 53de852e..c8c9d122 100644 --- a/tests/check_case_conflict_test.py +++ b/tests/check_case_conflict_test.py @@ -1,7 +1,24 @@ +import sys + +import pytest + from pre_commit_hooks.check_case_conflict import find_conflicting_filenames from pre_commit_hooks.check_case_conflict import main +from pre_commit_hooks.check_case_conflict import parents from pre_commit_hooks.util import cmd_output +skip_win32 = pytest.mark.skipif( + sys.platform == 'win32', + reason='case conflicts between directories and files', +) + + +def test_parents(): + assert set(parents('a')) == set() + assert set(parents('a/b')) == {'a'} + assert set(parents('a/b/c')) == {'a/b', 'a'} + assert set(parents('a/b/c/d')) == {'a/b/c', 'a/b', 'a'} + def test_nothing_added(temp_git_dir): with temp_git_dir.as_cwd(): @@ -26,6 +43,36 @@ def test_adding_something_with_conflict(temp_git_dir): assert find_conflicting_filenames(['f.py', 'F.py']) == 1 +@skip_win32 # pragma: win32 no cover +def test_adding_files_with_conflicting_directories(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('dir').join('x').write('foo') + temp_git_dir.mkdir('DIR').join('y').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + +@skip_win32 # pragma: win32 no cover +def test_adding_files_with_conflicting_deep_directories(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('x').mkdir('y').join('z').write('foo') + temp_git_dir.join('X').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + +@skip_win32 # pragma: win32 no cover +def test_adding_file_with_conflicting_directory(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('dir').join('x').write('foo') + temp_git_dir.join('DIR').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + def test_added_file_not_in_pre_commits_list(temp_git_dir): with temp_git_dir.as_cwd(): temp_git_dir.join('f.py').write("print('hello world')") @@ -46,6 +93,19 @@ def test_file_conflicts_with_committed_file(temp_git_dir): assert find_conflicting_filenames(['F.py']) == 1 +@skip_win32 # pragma: win32 no cover +def test_file_conflicts_with_committed_dir(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('dir').join('x').write('foo') + cmd_output('git', 'add', '-A') + cmd_output('git', 'commit', '--no-gpg-sign', '-n', '-m', 'Add f.py') + + temp_git_dir.join('DIR').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + def test_integration(temp_git_dir): with temp_git_dir.as_cwd(): assert main(argv=[]) == 0 From 45e252fc16f025fbca90d8b934d442593d4c61ba Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Apr 2021 17:08:26 +0000 Subject: [PATCH 150/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bea0d9e0..5c040f1d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: name-tests-test - id: double-quote-string-fixer - id: requirements-txt-fixer -- repo: https://gitlab.com/pycqa/flake8 +- repo: https://github.com/PyCQA/flake8 rev: 3.9.0 hooks: - id: flake8 From 4729918bc9e5bf7c409b04e111f8e416f351f3aa Mon Sep 17 00:00:00 2001 From: jack1142 <6032823+jack1142@users.noreply.github.com> Date: Tue, 6 Apr 2021 20:07:08 +0200 Subject: [PATCH 151/334] Disallow any branch name in checks_vcs_permalinks --- pre_commit_hooks/check_vcs_permalinks.py | 5 ++++- tests/check_vcs_permalinks_test.py | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_vcs_permalinks.py b/pre_commit_hooks/check_vcs_permalinks.py index a30277ce..5231d7af 100644 --- a/pre_commit_hooks/check_vcs_permalinks.py +++ b/pre_commit_hooks/check_vcs_permalinks.py @@ -8,7 +8,10 @@ def _get_pattern(domain: str) -> Pattern[bytes]: - regex = rf'https://{domain}/[^/ ]+/[^/ ]+/blob/master/[^# ]+#L\d+' + regex = ( + rf'https://{domain}/[^/ ]+/[^/ ]+/blob/' + r'(?![a-fA-F0-9]{4,64}/)([^/. ]+)/[^# ]+#L\d+' + ) return re.compile(regex.encode()) diff --git a/tests/check_vcs_permalinks_test.py b/tests/check_vcs_permalinks_test.py index 7d5f86c2..ad591515 100644 --- a/tests/check_vcs_permalinks_test.py +++ b/tests/check_vcs_permalinks_test.py @@ -11,6 +11,8 @@ def test_passing(tmpdir): f.write_binary( # permalinks are ok b'https://github.com/asottile/test/blob/649e6/foo%20bar#L1\n' + # tags are ok + b'https://github.com/asottile/test/blob/1.0.0/foo%20bar#L1\n' # links to files but not line numbers are ok b'https://github.com/asottile/test/blob/master/foo%20bar\n' # regression test for overly-greedy regex @@ -23,7 +25,8 @@ def test_failing(tmpdir, capsys): with tmpdir.as_cwd(): tmpdir.join('f.txt').write_binary( b'https://github.com/asottile/test/blob/master/foo#L1\n' - b'https://example.com/asottile/test/blob/master/foo#L1\n', + b'https://example.com/asottile/test/blob/master/foo#L1\n' + b'https://example.com/asottile/test/blob/main/foo#L1\n', ) assert main(('f.txt', '--additional-github-domain', 'example.com')) @@ -31,6 +34,7 @@ def test_failing(tmpdir, capsys): assert out == ( 'f.txt:1:https://github.com/asottile/test/blob/master/foo#L1\n' 'f.txt:2:https://example.com/asottile/test/blob/master/foo#L1\n' + 'f.txt:3:https://example.com/asottile/test/blob/main/foo#L1\n' '\n' 'Non-permanent github link detected.\n' 'On any page on github press [y] to load a permalink.\n' From f5e71a3dddd15f7f83496b487f852ab89571aa7e Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 8 Apr 2021 19:22:22 -0700 Subject: [PATCH 152/334] Update azure-pipelines template repositories Committed via https://github.com/asottile/all-repos --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c1ef4f4c..58dc61dd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -10,7 +10,7 @@ resources: type: github endpoint: github name: asottile/azure-pipeline-templates - ref: refs/tags/v1.0.0 + ref: refs/tags/v2.1.0 jobs: - template: job--python-tox.yml@asottile From 1fa820c84740ea9e982fabe2b2f2479dbd76c65f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 12 Apr 2021 17:10:06 +0000 Subject: [PATCH 153/334] [pre-commit.ci] pre-commit autoupdate --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5c040f1d..85604312 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.11.0 + rev: v2.12.0 hooks: - id: pyupgrade args: [--py36-plus] From b5d10ac89fc3ea5b23328ece32fafa568b6e4f52 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Apr 2021 17:08:17 +0000 Subject: [PATCH 154/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 3.9.0 → 3.9.1](https://github.com/PyCQA/flake8/compare/3.9.0...3.9.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 85604312..7ed2ca40 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://github.com/PyCQA/flake8 - rev: 3.9.0 + rev: 3.9.1 hooks: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] From 0423b8b21f93e857ca2543b4b5fb043860a2a781 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Apr 2021 17:18:44 +0000 Subject: [PATCH 155/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v2.4.0 → v2.5.0](https://github.com/asottile/reorder_python_imports/compare/v2.4.0...v2.5.0) - [github.com/asottile/pyupgrade: v2.12.0 → v2.13.0](https://github.com/asottile/pyupgrade/compare/v2.12.0...v2.13.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7ed2ca40..e9f9d8de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,12 +22,12 @@ repos: hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports - rev: v2.4.0 + rev: v2.5.0 hooks: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.12.0 + rev: v2.13.0 hooks: - id: pyupgrade args: [--py36-plus] From 4342783e1e61e167d5bda41ca8112c5456396066 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 17:17:27 +0000 Subject: [PATCH 156/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-autopep8: v1.5.6 → v1.5.7](https://github.com/pre-commit/mirrors-autopep8/compare/v1.5.6...v1.5.7) - [github.com/asottile/pyupgrade: v2.13.0 → v2.14.0](https://github.com/asottile/pyupgrade/compare/v2.13.0...v2.14.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e9f9d8de..c357c4f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.5.6 + rev: v1.5.7 hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.13.0 + rev: v2.14.0 hooks: - id: pyupgrade args: [--py36-plus] From 9e7cd9f13abb29ff8458407b905d522548eaf5c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 8 Jan 2021 17:27:16 +0200 Subject: [PATCH 157/334] Refactor check_executables_have_shebangs for git ls-files reuse --- .../check_executables_have_shebangs.py | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index 19f7ed27..e271c662 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -2,7 +2,9 @@ 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 @@ -19,29 +21,38 @@ def check_executables(paths: List[str]) -> int: else: # pragma: win32 no cover retv = 0 for path in paths: - if not _check_has_shebang(path): + if not has_shebang(path): _message(path) retv = 1 return retv -def _check_git_filemode(paths: Sequence[str]) -> int: +class GitLsFile(NamedTuple): + mode: str + filename: str + + +def git_ls_files(paths: Sequence[str]) -> Generator[GitLsFile, None, None]: outs = cmd_output('git', 'ls-files', '-z', '--stage', '--', *paths) - seen: Set[str] = set() for out in zsplit(outs): - metadata, path = out.split('\t') - tagmode = metadata.split(' ', 1)[0] + metadata, filename = out.split('\t') + mode, _, _ = metadata.split() + yield GitLsFile(mode, filename) - is_executable = any(b in EXECUTABLE_VALUES for b in tagmode[-3:]) - if is_executable and not _check_has_shebang(path): - _message(path) - seen.add(path) + +def _check_git_filemode(paths: Sequence[str]) -> int: + 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): + _message(ls_file.filename) + seen.add(ls_file.filename) return int(bool(seen)) -def _check_has_shebang(path: str) -> int: +def has_shebang(path: str) -> int: with open(path, 'rb') as f: first_bytes = f.read(2) From 391ae30a64e43a2bf743b9ecbed5894665c73327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 8 Jan 2021 17:36:55 +0200 Subject: [PATCH 158/334] Add check for executability of scripts with shebangs Closes https://github.com/pre-commit/pre-commit-hooks/issues/543 --- .pre-commit-hooks.yaml | 7 ++ README.md | 3 + .../check_shebang_scripts_are_executable.py | 53 +++++++++++ setup.cfg | 1 + ...eck_shebang_scripts_are_executable_test.py | 87 +++++++++++++++++++ 5 files changed, 151 insertions(+) create mode 100644 pre_commit_hooks/check_shebang_scripts_are_executable.py create mode 100644 tests/check_shebang_scripts_are_executable_test.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index fa617b97..0e089bca 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -52,6 +52,13 @@ entry: check-json language: python types: [json] +- id: check-shebang-scripts-are-executable + name: Check that scripts with shebangs are executable + description: Ensures that (non-binary) files with a shebang are executable. + entry: check-shebang-scripts-are-executable + language: python + types: [text] + stages: [commit, push, manual] - id: pretty-format-json name: Pretty format JSON description: This hook sets a standard for formatting JSON files. diff --git a/README.md b/README.md index bf36ecf1..d61d4576 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,9 @@ Attempts to load all json files to verify syntax. #### `check-merge-conflict` Check for files that contain merge conflict strings. +#### `check-shebang-scripts-are-executable` +Checks that scripts with shebangs are executable. + #### `check-symlinks` Checks for symlinks which do not point to anything. diff --git a/pre_commit_hooks/check_shebang_scripts_are_executable.py b/pre_commit_hooks/check_shebang_scripts_are_executable.py new file mode 100644 index 00000000..dce8c59d --- /dev/null +++ b/pre_commit_hooks/check_shebang_scripts_are_executable.py @@ -0,0 +1,53 @@ +"""Check that text files with a shebang are executable.""" +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: + # 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. + return _check_git_filemode(paths) + + +def _check_git_filemode(paths: Sequence[str]) -> int: + 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): + _message(ls_file.filename) + seen.add(ls_file.filename) + + return int(bool(seen)) + + +def _message(path: str) -> None: + print( + f'{path}: has a shebang but is not marked executable!\n' + f' If it is supposed to be executable, try: ' + f'`chmod +x {shlex.quote(path)}`\n' + f' If it not supposed to be executable, double-check its shebang ' + f'is wanted.\n', + file=sys.stderr, + ) + + +def main(argv: Optional[Sequence[str]] = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('filenames', nargs='*') + args = parser.parse_args(argv) + + return check_shebangs(args.filenames) + + +if __name__ == '__main__': + exit(main()) diff --git a/setup.cfg b/setup.cfg index 631faabb..dbe151b5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,6 +43,7 @@ console_scripts = check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main check-json = pre_commit_hooks.check_json:main check-merge-conflict = pre_commit_hooks.check_merge_conflict:main + check-shebang-scripts-are-executable = pre_commit_hooks.check_executables_have_shebangs:main_reverse check-symlinks = pre_commit_hooks.check_symlinks:main check-toml = pre_commit_hooks.check_toml:main check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main diff --git a/tests/check_shebang_scripts_are_executable_test.py b/tests/check_shebang_scripts_are_executable_test.py new file mode 100644 index 00000000..9e78b06c --- /dev/null +++ b/tests/check_shebang_scripts_are_executable_test.py @@ -0,0 +1,87 @@ +import os + +import pytest + +from pre_commit_hooks.check_shebang_scripts_are_executable import \ + _check_git_filemode +from pre_commit_hooks.check_shebang_scripts_are_executable import main +from pre_commit_hooks.util import cmd_output + + +def test_check_git_filemode_passing(tmpdir): + with tmpdir.as_cwd(): + cmd_output('git', 'init', '.') + + f = tmpdir.join('f') + f.write('#!/usr/bin/env bash') + f_path = str(f) + cmd_output('chmod', '+x', f_path) + cmd_output('git', 'add', f_path) + cmd_output('git', 'update-index', '--chmod=+x', f_path) + + g = tmpdir.join('g').ensure() + g_path = str(g) + cmd_output('git', 'add', g_path) + + files = [f_path, g_path] + assert _check_git_filemode(files) == 0 + + # this is the one we should trigger on + h = tmpdir.join('h') + h.write('#!/usr/bin/env bash') + h_path = str(h) + cmd_output('git', 'add', h_path) + + files = [h_path] + assert _check_git_filemode(files) == 1 + + +def test_check_git_filemode_passing_unusual_characters(tmpdir): + with tmpdir.as_cwd(): + cmd_output('git', 'init', '.') + + f = tmpdir.join('mañana.txt') + f.write('#!/usr/bin/env bash') + f_path = str(f) + cmd_output('chmod', '+x', f_path) + cmd_output('git', 'add', f_path) + cmd_output('git', 'update-index', '--chmod=+x', f_path) + + files = (f_path,) + assert _check_git_filemode(files) == 0 + + +def test_check_git_filemode_failing(tmpdir): + with tmpdir.as_cwd(): + cmd_output('git', 'init', '.') + + f = tmpdir.join('f').ensure() + f.write('#!/usr/bin/env bash') + f_path = str(f) + cmd_output('git', 'add', f_path) + + files = (f_path,) + assert _check_git_filemode(files) == 1 + + +@pytest.mark.parametrize( + ('content', 'mode', 'expected'), + ( + pytest.param('#!python', '+x', 0, id='shebang with executable'), + pytest.param('#!python', '-x', 1, id='shebang without executable'), + pytest.param('', '+x', 0, id='no shebang with executable'), + pytest.param('', '-x', 0, id='no shebang without executable'), + ), +) +def test_git_executable_shebang(temp_git_dir, content, mode, expected): + with temp_git_dir.as_cwd(): + path = temp_git_dir.join('path') + path.write(content) + cmd_output('git', 'add', str(path)) + cmd_output('chmod', mode, str(path)) + cmd_output('git', 'update-index', f'--chmod={mode}', str(path)) + + # simulate how identify chooses that something is executable + filenames = [path for path in [str(path)] if os.access(path, os.X_OK)] + + assert main(filenames) == expected From f90bef2772c562326071dc834482f3fb24ac14ba Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 May 2021 20:21:04 +0000 Subject: [PATCH 159/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 3.9.1 → 3.9.2](https://github.com/PyCQA/flake8/compare/3.9.1...3.9.2) - [github.com/asottile/pyupgrade: v2.14.0 → v2.15.0](https://github.com/asottile/pyupgrade/compare/v2.14.0...v2.15.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c357c4f3..93d9470f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://github.com/PyCQA/flake8 - rev: 3.9.1 + rev: 3.9.2 hooks: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.14.0 + rev: v2.15.0 hooks: - id: pyupgrade args: [--py36-plus] From 1995abf5569b98b0effc1b9c057184b7e1c74891 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 11 May 2021 13:09:44 -0700 Subject: [PATCH 160/334] remove deprecated autopep8-wrapper, flake8, pyflakes --- .pre-commit-hooks.yaml | 21 --------------------- README.md | 4 ---- 2 files changed, 25 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index a47f7339..a241d57b 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,10 +1,3 @@ -- id: autopep8-wrapper - name: autopep8 wrapper (removed) - description: (removed) use pre-commit/mirrors-autopep8 instead. - entry: pre-commit-hooks-removed autopep8-wrapper autopep8 https://github.com/pre-commit/mirrors-autopep8 - language: python - always_run: true - pass_filenames: false - id: check-added-large-files name: Check for added large files description: Prevent giant files from being committed @@ -143,13 +136,6 @@ entry: fix-encoding-pragma description: 'Add # -*- coding: utf-8 -*- to the top of python files' types: [python] -- id: flake8 - name: Flake8 (removed) - description: (removed) use gitlab.com/pycqa/flake8 instead. - entry: pre-commit-hooks-removed flake8 flake8 https://gitlab.com/pycqa/flake8 - language: python - always_run: true - pass_filenames: false - id: forbid-new-submodules name: Forbid new submodules language: python @@ -173,13 +159,6 @@ language: python pass_filenames: false always_run: true -- id: pyflakes - name: Pyflakes (removed) - description: (removed) use gitlab.com/pycqa/flake8 instead. - entry: pre-commit-hooks-removed pyflakes flake8 https://gitlab.com/pycqa/flake8 - language: python - always_run: true - pass_filenames: false - id: requirements-txt-fixer name: Fix requirements.txt description: Sorts entries in requirements.txt diff --git a/README.md b/README.md index 24d716fd..7cf5c652 100644 --- a/README.md +++ b/README.md @@ -180,10 +180,6 @@ Trims trailing whitespace. ### Deprecated / replaced hooks -- `autopep8-wrapper`: instead use - [mirrors-autopep8](https://github.com/pre-commit/mirrors-autopep8) -- `pyflakes`: instead use `flake8` -- `flake8`: instead use [upstream flake8](https://gitlab.com/pycqa/flake8) - `check-byte-order-marker`: instead use fix-byte-order-marker ### As a standalone package From a5cf10d9b26b197decab55dc76b5f5142124029a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Fri, 14 May 2021 19:12:09 -0700 Subject: [PATCH 161/334] Use more inclusive language Committed via https://github.com/asottile/all-repos --- tests/detect_aws_credentials_test.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/detect_aws_credentials_test.py b/tests/detect_aws_credentials_test.py index 4f00744e..72125099 100644 --- a/tests/detect_aws_credentials_test.py +++ b/tests/detect_aws_credentials_test.py @@ -13,15 +13,15 @@ ('env_vars', 'values'), ( ({}, set()), - ({'AWS_DUMMY_KEY': '/foo'}, set()), + ({'AWS_PLACEHOLDER_KEY': '/foo'}, set()), ({'AWS_CONFIG_FILE': '/foo'}, {'/foo'}), ({'AWS_CREDENTIAL_FILE': '/foo'}, {'/foo'}), ({'AWS_SHARED_CREDENTIALS_FILE': '/foo'}, {'/foo'}), ({'BOTO_CONFIG': '/foo'}, {'/foo'}), - ({'AWS_DUMMY_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar'}, {'/bar'}), + ({'AWS_PLACEHOLDER_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar'}, {'/bar'}), ( { - 'AWS_DUMMY_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar', + 'AWS_PLACEHOLDER_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar', 'AWS_CREDENTIAL_FILE': '/baz', }, {'/bar', '/baz'}, @@ -44,13 +44,16 @@ def test_get_aws_credentials_file_from_env(env_vars, values): ('env_vars', 'values'), ( ({}, set()), - ({'AWS_DUMMY_KEY': 'foo'}, set()), + ({'AWS_PLACEHOLDER_KEY': 'foo'}, set()), ({'AWS_SECRET_ACCESS_KEY': 'foo'}, {'foo'}), ({'AWS_SECURITY_TOKEN': 'foo'}, {'foo'}), ({'AWS_SESSION_TOKEN': 'foo'}, {'foo'}), ({'AWS_SESSION_TOKEN': ''}, set()), ({'AWS_SESSION_TOKEN': 'foo', 'AWS_SECURITY_TOKEN': ''}, {'foo'}), - ({'AWS_DUMMY_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'}, {'bar'}), + ( + {'AWS_PLACEHOLDER_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'}, + {'bar'}, + ), ( {'AWS_SECRET_ACCESS_KEY': 'foo', 'AWS_SECURITY_TOKEN': 'bar'}, {'foo', 'bar'}, From 9cc62e1a631dd72a054fb2dccda6fdebd99aacab Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Fri, 14 May 2021 20:17:35 -0700 Subject: [PATCH 162/334] v4.0.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 36 ++++++++++++++++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 93d9470f..a819f5c1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 5de3576e..4a883355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,39 @@ +4.0.0 - 2021-05-14 +================== + +### Features +- `check-json`: report duplicate keys. + - #558 PR by @AdityaKhursale. + - #554 issue by @adamchainz. +- `no-commit-to-branch`: add `main` to default blocked branches. + - #565 PR by @ndevenish. +- `check-case-conflict`: check conflicts in directory names as well. + - #575 PR by @slsyy. + - #70 issue by @andyjack. +- `check-vcs-permalinks`: forbid other branch names. + - #582 PR by @jack1142. + - #581 issue by @jack1142. +- `check-shebang-scripts-are-executable`: new hook which ensures shebang'd + scripts are executable. + - #545 PR by @scop. + +### Fixes +- `check-executables-have-shebangs`: Short circuit shebang lookup on windows. + - #544 PR by @scop. +- `requirements-txt-fixer`: Fix comments which have indentation + - #549 PR by @greshilov. + - #548 issue by @greshilov. +- `pretty-format-json`: write to stdout using UTF-8 encoding. + - #571 PR by @jack1142. + - #570 issue by @jack1142. +- Use more inclusive language. + - #599 PR by @asottile. + +### Breaking changes +- Remove deprecated hooks: `flake8`, `pyflakes`, `autopep8-wrapper`. + - #597 PR by @asottile. + + 3.4.0 - 2020-12-15 ================== diff --git a/README.md b/README.md index 5a6ddfef..e7d9b23a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 # Use the ref you want to point at + rev: v4.0.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index dbe151b5..7fdab7d6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 3.4.0 +version = 4.0.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From fed8b6debb1b94d8e4d29aa12d95dbb01b1e2418 Mon Sep 17 00:00:00 2001 From: Iago Alonso Date: Sat, 15 May 2021 12:29:30 +0200 Subject: [PATCH 163/334] Rename file causing `check-json` to fail - `mv duplicated_key_json.{json,notjson}` - change reference to the file in `tests/check_json_test.py` Fixes #600 --- .../{duplicate_key_json.json => duplicate_key_json.notjson} | 0 tests/check_json_test.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename testing/resources/{duplicate_key_json.json => duplicate_key_json.notjson} (100%) diff --git a/testing/resources/duplicate_key_json.json b/testing/resources/duplicate_key_json.notjson similarity index 100% rename from testing/resources/duplicate_key_json.json rename to testing/resources/duplicate_key_json.notjson diff --git a/tests/check_json_test.py b/tests/check_json_test.py index e010faaa..3ec67f1c 100644 --- a/tests/check_json_test.py +++ b/tests/check_json_test.py @@ -9,7 +9,7 @@ ('bad_json.notjson', 1), ('bad_json_latin1.nonjson', 1), ('ok_json.json', 0), - ('duplicate_key_json.json', 1), + ('duplicate_key_json.notjson', 1), ), ) def test_main(capsys, filename, expected_retval): From bb4eef160d784e365048203fa26d051bc4a1079b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sun, 16 May 2021 13:23:23 +0300 Subject: [PATCH 164/334] fix: check-shebang-scripts-are-executable entry point Closes https://github.com/pre-commit/pre-commit-hooks/issues/602 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 7fdab7d6..ddfea2ae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,7 +43,7 @@ console_scripts = check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main check-json = pre_commit_hooks.check_json:main check-merge-conflict = pre_commit_hooks.check_merge_conflict:main - check-shebang-scripts-are-executable = pre_commit_hooks.check_executables_have_shebangs:main_reverse + check-shebang-scripts-are-executable = pre_commit_hooks.check_shebang_scripts_are_executable:main check-symlinks = pre_commit_hooks.check_symlinks:main check-toml = pre_commit_hooks.check_toml:main check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main From 38b88246ccc552bffaaf54259d064beeee434539 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 16 May 2021 08:29:57 -0700 Subject: [PATCH 165/334] v4.0.1 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a819f5c1..2bd89e0d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.0 + rev: v4.0.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a883355..530c4c8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +4.0.1 - 2021-05-16 +================== + +### Fixes +- `check-shebang-scripts-are-executable` fix entry point. + - #602 issue by @Person-93. + - #603 PR by @scop. + 4.0.0 - 2021-05-14 ================== diff --git a/README.md b/README.md index e7d9b23a..7486aba2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.0 # Use the ref you want to point at + rev: v4.0.1 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index ddfea2ae..fc579392 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.0.0 +version = 4.0.1 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From d1fac7f826abf3b3f32b0d3d71d25f743f1f7c46 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 17:23:36 +0000 Subject: [PATCH 166/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.15.0 → v2.16.0](https://github.com/asottile/pyupgrade/compare/v2.15.0...v2.16.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2bd89e0d..84addcf1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.15.0 + rev: v2.16.0 hooks: - id: pyupgrade args: [--py36-plus] From a4f7dedfed55bebe5469c1dfb07004d9d5a36002 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 May 2021 17:20:10 +0000 Subject: [PATCH 167/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.16.0 → v2.18.2](https://github.com/asottile/pyupgrade/compare/v2.16.0...v2.18.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 84addcf1..6f2262c1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.16.0 + rev: v2.18.2 hooks: - id: pyupgrade args: [--py36-plus] From 2d040b429d56b1bc3bbc29524e5f1df984ca3db8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 31 May 2021 17:25:23 +0000 Subject: [PATCH 168/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.18.2 → v2.19.0](https://github.com/asottile/pyupgrade/compare/v2.18.2...v2.19.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6f2262c1..e39a630a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.18.2 + rev: v2.19.0 hooks: - id: pyupgrade args: [--py36-plus] From 00948d0833e82eb28c23915d6ff3f92df116239f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Jun 2021 01:46:25 +0000 Subject: [PATCH 169/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.19.0 → v2.19.1](https://github.com/asottile/pyupgrade/compare/v2.19.0...v2.19.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e39a630a..aaeccc4e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.19.0 + rev: v2.19.1 hooks: - id: pyupgrade args: [--py36-plus] From 172a87e6a8454f2f35d0c2e6875141d3f97a0325 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Jun 2021 17:34:07 +0000 Subject: [PATCH 170/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.19.1 → v2.19.4](https://github.com/asottile/pyupgrade/compare/v2.19.1...v2.19.4) - [github.com/pre-commit/mirrors-mypy: v0.812 → v0.902](https://github.com/pre-commit/mirrors-mypy/compare/v0.812...v0.902) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aaeccc4e..5084ff5e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.19.1 + rev: v2.19.4 hooks: - id: pyupgrade args: [--py36-plus] @@ -41,6 +41,6 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.812 + rev: v0.902 hooks: - id: mypy From fabe3d8855a009165a5ff6863a906ad886600882 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 14 Jun 2021 11:30:37 -0700 Subject: [PATCH 171/334] Add mypy dependency on types-all --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5084ff5e..b7cc5ca1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,3 +44,4 @@ repos: rev: v0.902 hooks: - id: mypy + additional_dependencies: [types-all] From 41b29e8c8d95a4f4d61fc2fec2c0e3857c45ef06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Can=20Sar=C4=B1g=C3=B6l?= Date: Tue, 15 Jun 2021 09:28:11 +0200 Subject: [PATCH 172/334] Added pdbr into debug statements --- pre_commit_hooks/debug_statement_hook.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 794f7080..0abac506 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -10,6 +10,7 @@ DEBUG_STATEMENTS = { 'ipdb', 'pdb', + 'pdbr', 'pudb', 'pydevd_pycharm', 'q', From 8041dff63fd5b609846b0214c7b87b3844995d79 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 21 Jun 2021 19:15:42 -0700 Subject: [PATCH 173/334] stricter mypy settings Committed via https://github.com/asottile/all-repos --- setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index fc579392..a5ad401a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -80,6 +80,8 @@ disallow_any_generics = true disallow_incomplete_defs = true disallow_untyped_defs = true no_implicit_optional = true +warn_redundant_casts = true +warn_unused_ignores = true [mypy-testing.*] disallow_untyped_defs = false From de3f6c33c7330358c7d9dea5b6777dbbb271a9ec Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Jun 2021 17:37:51 +0000 Subject: [PATCH 174/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.902 → v0.910](https://github.com/pre-commit/mirrors-mypy/compare/v0.902...v0.910) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b7cc5ca1..ef3d6d7a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.902 + rev: v0.910 hooks: - id: mypy additional_dependencies: [types-all] From 469e4b83f546f2845394df15058708610611b943 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Jul 2021 22:02:26 +0000 Subject: [PATCH 175/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.19.4 → v2.20.0](https://github.com/asottile/pyupgrade/compare/v2.19.4...v2.20.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef3d6d7a..69b6d672 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.19.4 + rev: v2.20.0 hooks: - id: pyupgrade args: [--py36-plus] From 301195efa96f98269eb1d473e3bec00cb228b3b8 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 7 Jul 2021 14:06:01 -0400 Subject: [PATCH 176/334] use shutil.which instead of distutils.spawn --- tests/check_added_large_files_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index ff53b05b..d98d99b5 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -1,4 +1,4 @@ -import distutils.spawn +import shutil import pytest @@ -75,7 +75,7 @@ def test_integration(temp_git_dir): def has_gitlfs(): - return distutils.spawn.find_executable('git-lfs') is not None + return shutil.which('git-lfs') is not None xfailif_no_gitlfs = pytest.mark.xfail( From 8a4333fcff4ee5fbd5e9ce8e49269301989311ff Mon Sep 17 00:00:00 2001 From: Guy Kisel Date: Fri, 9 Jul 2021 12:26:07 -0700 Subject: [PATCH 177/334] optimize check_case_conflict.parents --- pre_commit_hooks/check_case_conflict.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py index 024c1c3c..d7ab860e 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -15,10 +15,11 @@ def lower_set(iterable: Iterable[str]) -> Set[str]: def parents(file: str) -> Iterator[str]: - file = os.path.dirname(file) - while file: - yield file - file = os.path.dirname(file) + path_parts = file.split('/') + path_parts.pop() + while path_parts: + yield '/'.join(path_parts) + path_parts.pop() def directories_for(files: Set[str]) -> Set[str]: From 24681673712576b51def54b24e280eacbb877a20 Mon Sep 17 00:00:00 2001 From: Guy Kisel Date: Fri, 9 Jul 2021 12:29:20 -0700 Subject: [PATCH 178/334] remove unused os.path --- pre_commit_hooks/check_case_conflict.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py index d7ab860e..712b993f 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -1,5 +1,4 @@ import argparse -import os.path from typing import Iterable from typing import Iterator from typing import Optional From b008acc8b6c115c8f0c9835d72848ab5394e5311 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 12 Jul 2021 23:21:11 +0000 Subject: [PATCH 179/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.20.0 → v2.21.0](https://github.com/asottile/pyupgrade/compare/v2.20.0...v2.21.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 69b6d672..4eb0aef6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.20.0 + rev: v2.21.0 hooks: - id: pyupgrade args: [--py36-plus] From e9689b29b0b5d4edd8ee020d4861d0a2827e44a8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Jul 2021 21:58:23 +0000 Subject: [PATCH 180/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.21.0 → v2.21.2](https://github.com/asottile/pyupgrade/compare/v2.21.0...v2.21.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4eb0aef6..a2e4c9b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.21.0 + rev: v2.21.2 hooks: - id: pyupgrade args: [--py36-plus] From 5758076a55fd77a279f331a2f425d62a62f18585 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Jul 2021 17:52:23 +0000 Subject: [PATCH 181/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v2.5.0 → v2.6.0](https://github.com/asottile/reorder_python_imports/compare/v2.5.0...v2.6.0) - [github.com/asottile/pyupgrade: v2.21.2 → v2.23.0](https://github.com/asottile/pyupgrade/compare/v2.21.2...v2.23.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a2e4c9b7..19c0cc01 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,12 +22,12 @@ repos: hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports - rev: v2.5.0 + rev: v2.6.0 hooks: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.21.2 + rev: v2.23.0 hooks: - id: pyupgrade args: [--py36-plus] From caca3a9aec275868d924949eb80e6ebb2af1f588 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Aug 2021 18:01:41 +0000 Subject: [PATCH 182/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.23.0 → v2.23.1](https://github.com/asottile/pyupgrade/compare/v2.23.0...v2.23.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19c0cc01..174f77cc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.23.0 + rev: v2.23.1 hooks: - id: pyupgrade args: [--py36-plus] From 5be200da581a74b73e9aa95ef6f9923060193d72 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Aug 2021 18:04:14 +0000 Subject: [PATCH 183/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.23.1 → v2.23.3](https://github.com/asottile/pyupgrade/compare/v2.23.1...v2.23.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 174f77cc..e679fd3b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.23.1 + rev: v2.23.3 hooks: - id: pyupgrade args: [--py36-plus] From 10c5e4e166c5546f809d7fe757d35036f17d46a3 Mon Sep 17 00:00:00 2001 From: Mikhail Khvoinitsky Date: Wed, 23 Jun 2021 03:10:13 +0300 Subject: [PATCH 184/334] forbid-new-submodules: fix triggering failure when only a submodule is committed (without any other file); support --from-ref and --to-ref; fixes #609 --- .pre-commit-hooks.yaml | 1 + pre_commit_hooks/forbid_new_submodules.py | 21 ++++++++++++--- testing/util.py | 6 +++++ tests/check_added_large_files_test.py | 3 ++- tests/check_case_conflict_test.py | 5 ++-- tests/check_merge_conflict_test.py | 13 ++++----- tests/destroyed_symlinks_test.py | 5 ++-- tests/forbid_new_submodules_test.py | 33 ++++++++++++++++------- tests/no_commit_to_branch_test.py | 3 ++- 9 files changed, 65 insertions(+), 25 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 91dbdf0b..646a0bb9 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -154,6 +154,7 @@ language: python entry: forbid-new-submodules description: Prevent addition of new git submodules + types: [directory] - id: mixed-line-ending name: Mixed line ending description: Replaces or checks mixed line ending diff --git a/pre_commit_hooks/forbid_new_submodules.py b/pre_commit_hooks/forbid_new_submodules.py index c144d728..9d1aa2f5 100644 --- a/pre_commit_hooks/forbid_new_submodules.py +++ b/pre_commit_hooks/forbid_new_submodules.py @@ -1,3 +1,5 @@ +import argparse +import os from typing import Optional from typing import Sequence @@ -5,10 +7,23 @@ def main(argv: Optional[Sequence[str]] = None) -> int: - # `argv` is ignored, pre-commit will send us a list of files that we - # don't care about + parser = argparse.ArgumentParser() + parser.add_argument('filenames', nargs='*') + args = parser.parse_args(argv) + + if ( + 'PRE_COMMIT_FROM_REF' in os.environ and + 'PRE_COMMIT_TO_REF' in os.environ + ): + diff_arg = '...'.join(( + os.environ['PRE_COMMIT_FROM_REF'], + os.environ['PRE_COMMIT_TO_REF'], + )) + else: + diff_arg = '--staged' added_diff = cmd_output( - 'git', 'diff', '--staged', '--diff-filter=A', '--raw', + 'git', 'diff', '--diff-filter=A', '--raw', diff_arg, '--', + *args.filenames, ) retv = 0 for line in added_diff.splitlines(): diff --git a/testing/util.py b/testing/util.py index 8e468d60..50437544 100644 --- a/testing/util.py +++ b/testing/util.py @@ -1,4 +1,5 @@ import os.path +import subprocess TESTING_DIR = os.path.abspath(os.path.dirname(__file__)) @@ -6,3 +7,8 @@ def get_resource_path(path): return os.path.join(TESTING_DIR, 'resources', path) + + +def git_commit(*args, **kwargs): + cmd = ('git', 'commit', '--no-gpg-sign', '--no-verify', '--no-edit', *args) + subprocess.check_call(cmd, **kwargs) diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index d98d99b5..d38c4f67 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -5,6 +5,7 @@ from pre_commit_hooks.check_added_large_files import find_large_added_files from pre_commit_hooks.check_added_large_files import main from pre_commit_hooks.util import cmd_output +from testing.util import git_commit def test_nothing_added(temp_git_dir): @@ -104,7 +105,7 @@ def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover # First add the file we're going to move temp_git_dir.join('a.bin').write('a' * 10000) cmd_output('git', 'add', '--', '.') - cmd_output('git', 'commit', '--no-gpg-sign', '-am', 'foo') + git_commit('-am', 'foo') # Now move it and make sure the hook still succeeds cmd_output('git', 'mv', 'a.bin', 'b.bin') assert main(('--maxkb', '9', 'b.bin')) == 0 diff --git a/tests/check_case_conflict_test.py b/tests/check_case_conflict_test.py index c8c9d122..d9211b57 100644 --- a/tests/check_case_conflict_test.py +++ b/tests/check_case_conflict_test.py @@ -6,6 +6,7 @@ from pre_commit_hooks.check_case_conflict import main from pre_commit_hooks.check_case_conflict import parents from pre_commit_hooks.util import cmd_output +from testing.util import git_commit skip_win32 = pytest.mark.skipif( sys.platform == 'win32', @@ -85,7 +86,7 @@ def test_file_conflicts_with_committed_file(temp_git_dir): with temp_git_dir.as_cwd(): temp_git_dir.join('f.py').write("print('hello world')") cmd_output('git', 'add', 'f.py') - cmd_output('git', 'commit', '--no-gpg-sign', '-n', '-m', 'Add f.py') + git_commit('-m', 'Add f.py') temp_git_dir.join('F.py').write("print('hello world')") cmd_output('git', 'add', 'F.py') @@ -98,7 +99,7 @@ def test_file_conflicts_with_committed_dir(temp_git_dir): with temp_git_dir.as_cwd(): temp_git_dir.mkdir('dir').join('x').write('foo') cmd_output('git', 'add', '-A') - cmd_output('git', 'commit', '--no-gpg-sign', '-n', '-m', 'Add f.py') + git_commit('-m', 'Add f.py') temp_git_dir.join('DIR').write('foo') cmd_output('git', 'add', '-A') diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index fccf41ff..de07bc17 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -6,6 +6,7 @@ from pre_commit_hooks.check_merge_conflict import main from pre_commit_hooks.util import cmd_output from testing.util import get_resource_path +from testing.util import git_commit @pytest.fixture @@ -20,19 +21,19 @@ def f1_is_a_conflict_file(tmpdir): with repo1.as_cwd(): repo1_f1.ensure() cmd_output('git', 'add', '.') - cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'commit1') + git_commit('-m', 'commit1') cmd_output('git', 'clone', str(repo1), str(repo2)) # Commit in master with repo1.as_cwd(): repo1_f1.write('parent\n') - cmd_output('git', 'commit', '--no-gpg-sign', '-am', 'master commit2') + git_commit('-am', 'master commit2') # Commit in clone and pull with repo2.as_cwd(): repo2_f1.write('child\n') - cmd_output('git', 'commit', '--no-gpg-sign', '-am', 'clone commit2') + git_commit('-am', 'clone commit2') cmd_output('git', 'pull', '--no-rebase', retcode=None) # We should end up in a merge conflict! f1 = repo2_f1.read() @@ -75,20 +76,20 @@ def repository_pending_merge(tmpdir): with repo1.as_cwd(): repo1_f1.ensure() cmd_output('git', 'add', '.') - cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'commit1') + git_commit('-m', 'commit1') cmd_output('git', 'clone', str(repo1), str(repo2)) # Commit in master with repo1.as_cwd(): repo1_f1.write('parent\n') - cmd_output('git', 'commit', '--no-gpg-sign', '-am', 'master commit2') + git_commit('-am', 'master commit2') # Commit in clone and pull without committing with repo2.as_cwd(): repo2_f2.write('child\n') cmd_output('git', 'add', '.') - cmd_output('git', 'commit', '--no-gpg-sign', '-m', 'clone commit2') + git_commit('-m', 'clone commit2') cmd_output('git', 'pull', '--no-commit', '--no-rebase') # We should end up in a pending merge assert repo2_f1.read() == 'parent\n' diff --git a/tests/destroyed_symlinks_test.py b/tests/destroyed_symlinks_test.py index d2c90310..cde06cfb 100644 --- a/tests/destroyed_symlinks_test.py +++ b/tests/destroyed_symlinks_test.py @@ -5,6 +5,7 @@ from pre_commit_hooks.destroyed_symlinks import find_destroyed_symlinks from pre_commit_hooks.destroyed_symlinks import main +from testing.util import git_commit TEST_SYMLINK = 'test_symlink' TEST_SYMLINK_TARGET = '/doesnt/really/matters' @@ -23,9 +24,7 @@ def repo_with_destroyed_symlink(tmpdir): with open(TEST_FILE, 'w') as f: print('some random content', file=f) subprocess.check_call(('git', 'add', '.')) - subprocess.check_call( - ('git', 'commit', '--no-gpg-sign', '-m', 'initial'), - ) + git_commit('-m', 'initial') assert b'120000 ' in subprocess.check_output( ('git', 'cat-file', '-p', 'HEAD^{tree}'), ) diff --git a/tests/forbid_new_submodules_test.py b/tests/forbid_new_submodules_test.py index 4871ae7f..0326d941 100644 --- a/tests/forbid_new_submodules_test.py +++ b/tests/forbid_new_submodules_test.py @@ -1,22 +1,20 @@ +import os import subprocess +from unittest import mock import pytest from pre_commit_hooks.forbid_new_submodules import main +from testing.util import git_commit @pytest.fixture def git_dir_with_git_dir(tmpdir): with tmpdir.as_cwd(): subprocess.check_call(('git', 'init', '.')) - subprocess.check_call(( - 'git', 'commit', '-m', 'init', '--allow-empty', '--no-gpg-sign', - )) + git_commit('--allow-empty', '-m', 'init') subprocess.check_call(('git', 'init', 'foo')) - subprocess.check_call( - ('git', 'commit', '-m', 'init', '--allow-empty', '--no-gpg-sign'), - cwd=str(tmpdir.join('foo')), - ) + git_commit('--allow-empty', '-m', 'init', cwd=str(tmpdir.join('foo'))) yield @@ -31,7 +29,24 @@ def git_dir_with_git_dir(tmpdir): ) def test_main_new_submodule(git_dir_with_git_dir, capsys, cmd): subprocess.check_call(cmd) - assert main() == 1 + assert main(('random_non-related_file',)) == 0 + assert main(('foo',)) == 1 + out, _ = capsys.readouterr() + assert out.startswith('foo: new submodule introduced\n') + + +def test_main_new_submodule_committed(git_dir_with_git_dir, capsys): + rev_parse_cmd = ('git', 'rev-parse', 'HEAD') + from_ref = subprocess.check_output(rev_parse_cmd).decode().strip() + subprocess.check_call(('git', 'submodule', 'add', './foo')) + git_commit('-m', 'new submodule') + to_ref = subprocess.check_output(rev_parse_cmd).decode().strip() + with mock.patch.dict( + os.environ, + {'PRE_COMMIT_FROM_REF': from_ref, 'PRE_COMMIT_TO_REF': to_ref}, + ): + assert main(('random_non-related_file',)) == 0 + assert main(('foo',)) == 1 out, _ = capsys.readouterr() assert out.startswith('foo: new submodule introduced\n') @@ -39,4 +54,4 @@ def test_main_new_submodule(git_dir_with_git_dir, capsys, cmd): def test_main_no_new_submodule(git_dir_with_git_dir): open('test.py', 'a+').close() subprocess.check_call(('git', 'add', 'test.py')) - assert main() == 0 + assert main(('test.py',)) == 0 diff --git a/tests/no_commit_to_branch_test.py b/tests/no_commit_to_branch_test.py index 610e660e..9fcb5808 100644 --- a/tests/no_commit_to_branch_test.py +++ b/tests/no_commit_to_branch_test.py @@ -3,6 +3,7 @@ from pre_commit_hooks.no_commit_to_branch import is_on_branch from pre_commit_hooks.no_commit_to_branch import main from pre_commit_hooks.util import cmd_output +from testing.util import git_commit def test_other_branch(temp_git_dir): @@ -62,7 +63,7 @@ def test_main_default_call(temp_git_dir): def test_not_on_a_branch(temp_git_dir): with temp_git_dir.as_cwd(): - cmd_output('git', 'commit', '--no-gpg-sign', '--allow-empty', '-m1') + git_commit('--allow-empty', '-m1') head = cmd_output('git', 'rev-parse', 'HEAD').strip() cmd_output('git', 'checkout', head) # we're not on a branch! From 332a621dd92d7b22a44fd4b4d6ea47e48c4d22bc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 18:12:39 +0000 Subject: [PATCH 185/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.23.3 → v2.24.0](https://github.com/asottile/pyupgrade/compare/v2.23.3...v2.24.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e679fd3b..421c8880 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.23.3 + rev: v2.24.0 hooks: - id: pyupgrade args: [--py36-plus] From 383841026105ff812a5f87ddd6acb5656d3984e1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 18:37:07 +0000 Subject: [PATCH 186/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.24.0 → v2.25.0](https://github.com/asottile/pyupgrade/compare/v2.24.0...v2.25.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 421c8880..af2c89c3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.24.0 + rev: v2.25.0 hooks: - id: pyupgrade args: [--py36-plus] From 5a8726e37c0a53bddd43429dcdf8c5939aa55bd4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 18:50:52 +0000 Subject: [PATCH 187/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.25.0 → v2.26.0](https://github.com/asottile/pyupgrade/compare/v2.25.0...v2.26.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af2c89c3..2cd4a743 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.25.0 + rev: v2.26.0 hooks: - id: pyupgrade args: [--py36-plus] From 1822f1b60a0fd71ee82945cfc945158b1f991449 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Sep 2021 18:49:03 +0000 Subject: [PATCH 188/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.26.0 → v2.28.0](https://github.com/asottile/pyupgrade/compare/v2.26.0...v2.28.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2cd4a743..b8c50cef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.26.0 + rev: v2.28.0 hooks: - id: pyupgrade args: [--py36-plus] From ccdf02dfd48be0656f3b33ded45e629296344db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Ferreira?= Date: Sat, 2 Oct 2021 20:33:35 +0100 Subject: [PATCH 189/334] detect_private_key: add textual version of `PKCS #8` encrypted private keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As described by RFC7468 and RFC5958, keys that are encoded using the "ENCRYPTED PRIVATE KEY" label are described as private key information and therefore can contain secrets, even though encrypted. Signed-off-by: Luís Ferreira --- pre_commit_hooks/detect_private_key.py | 1 + tests/detect_private_key_test.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pre_commit_hooks/detect_private_key.py b/pre_commit_hooks/detect_private_key.py index 7bbc2f91..bd1f2962 100644 --- a/pre_commit_hooks/detect_private_key.py +++ b/pre_commit_hooks/detect_private_key.py @@ -11,6 +11,7 @@ b'PuTTY-User-Key-File-2', b'BEGIN SSH2 ENCRYPTED PRIVATE KEY', b'BEGIN PGP PRIVATE KEY BLOCK', + b'BEGIN ENCRYPTED PRIVATE KEY', ] diff --git a/tests/detect_private_key_test.py b/tests/detect_private_key_test.py index 72810008..9495047b 100644 --- a/tests/detect_private_key_test.py +++ b/tests/detect_private_key_test.py @@ -10,6 +10,7 @@ (b'-----BEGIN OPENSSH PRIVATE KEY-----', 1), (b'PuTTY-User-Key-File-2: ssh-rsa', 1), (b'---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----', 1), + (b'-----BEGIN ENCRYPTED PRIVATE KEY-----', 1), (b'ssh-rsa DATA', 0), (b'ssh-dsa DATA', 0), # Some arbitrary binary data From 1b4e30e9aaebad246088f2493b3fdbbc04991686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Ferreira?= Date: Sat, 2 Oct 2021 20:42:15 +0100 Subject: [PATCH 190/334] detect_private_key: add OpenVPN shared-secret key block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'OpenVPN Static key V1' label is often used by OpenVPN for providing hardening security with additional HMAC signatures to the SSL/TLS handshake packets. They are shared secrets and should be kept private. Signed-off-by: Luís Ferreira --- pre_commit_hooks/detect_private_key.py | 1 + tests/detect_private_key_test.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pre_commit_hooks/detect_private_key.py b/pre_commit_hooks/detect_private_key.py index bd1f2962..3a6027da 100644 --- a/pre_commit_hooks/detect_private_key.py +++ b/pre_commit_hooks/detect_private_key.py @@ -12,6 +12,7 @@ b'BEGIN SSH2 ENCRYPTED PRIVATE KEY', b'BEGIN PGP PRIVATE KEY BLOCK', b'BEGIN ENCRYPTED PRIVATE KEY', + b'BEGIN OpenVPN Static key V1', ] diff --git a/tests/detect_private_key_test.py b/tests/detect_private_key_test.py index 9495047b..d2c724f0 100644 --- a/tests/detect_private_key_test.py +++ b/tests/detect_private_key_test.py @@ -11,6 +11,7 @@ (b'PuTTY-User-Key-File-2: ssh-rsa', 1), (b'---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----', 1), (b'-----BEGIN ENCRYPTED PRIVATE KEY-----', 1), + (b'-----BEGIN OpenVPN Static key V1-----', 1), (b'ssh-rsa DATA', 0), (b'ssh-dsa DATA', 0), # Some arbitrary binary data From 3e75bdde12fea3bac1529f3de0cdc215b5da7161 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Oct 2021 18:54:32 +0000 Subject: [PATCH 191/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.28.0 → v2.29.0](https://github.com/asottile/pyupgrade/compare/v2.28.0...v2.29.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b8c50cef..0f408494 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.28.0 + rev: v2.29.0 hooks: - id: pyupgrade args: [--py36-plus] From 633151a3dfb7b7dc0e464fe7ae585b372cb0ed29 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Oct 2021 18:54:03 +0000 Subject: [PATCH 192/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 3.9.2 → 4.0.1](https://github.com/PyCQA/flake8/compare/3.9.2...4.0.1) - [github.com/asottile/setup-cfg-fmt: v1.17.0 → v1.18.0](https://github.com/asottile/setup-cfg-fmt/compare/v1.17.0...v1.18.0) - [github.com/pre-commit/mirrors-mypy: v0.910 → v0.910-1](https://github.com/pre-commit/mirrors-mypy/compare/v0.910...v0.910-1) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0f408494..4c42d392 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: double-quote-string-fixer - id: requirements-txt-fixer - repo: https://github.com/PyCQA/flake8 - rev: 3.9.2 + rev: 4.0.1 hooks: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] @@ -37,11 +37,11 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.17.0 + rev: v1.18.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.910 + rev: v0.910-1 hooks: - id: mypy additional_dependencies: [types-all] From 262c12aba282c2f9a52494b6278088ef7f82ec44 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Oct 2021 18:54:31 +0000 Subject: [PATCH 193/334] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index a5ad401a..890d6295 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,6 +17,7 @@ classifiers = Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy From 07af54024c92ce32e17cafb1f22a827bbd8f77d6 Mon Sep 17 00:00:00 2001 From: Ersin Yildirim <9623746+errsyn@users.noreply.github.com> Date: Mon, 4 Oct 2021 21:50:38 +0200 Subject: [PATCH 194/334] Adjust git dir when checking for merge in worktree --- pre_commit_hooks/check_merge_conflict.py | 13 ++++++++----- tests/check_merge_conflict_test.py | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index c20a8af7..dc25b29a 100644 --- a/pre_commit_hooks/check_merge_conflict.py +++ b/pre_commit_hooks/check_merge_conflict.py @@ -3,6 +3,8 @@ from typing import Optional from typing import Sequence +from pre_commit_hooks.util import cmd_output + CONFLICT_PATTERNS = [ b'<<<<<<< ', @@ -12,13 +14,14 @@ ] -def is_in_merge() -> int: +def is_in_merge() -> bool: + git_dir = cmd_output('git', 'rev-parse', '--git-dir').rstrip() return ( - os.path.exists(os.path.join('.git', 'MERGE_MSG')) and + os.path.exists(os.path.join(git_dir, 'MERGE_MSG')) and ( - os.path.exists(os.path.join('.git', 'MERGE_HEAD')) or - os.path.exists(os.path.join('.git', 'rebase-apply')) or - os.path.exists(os.path.join('.git', 'rebase-merge')) + os.path.exists(os.path.join(git_dir, 'MERGE_HEAD')) or + os.path.exists(os.path.join(git_dir, 'rebase-apply')) or + os.path.exists(os.path.join(git_dir, 'rebase-merge')) ) ) diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index de07bc17..79c1b118 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -135,3 +135,15 @@ def test_care_when_assumed_merge(tmpdir): f = tmpdir.join('README.md') f.write_binary(b'problem\n=======\n') assert main([str(f.realpath()), '--assume-in-merge']) == 1 + + +def test_worktree_merge_conflicts(f1_is_a_conflict_file, tmpdir): + worktree = tmpdir.join('worktree') + cmd_output('git', 'worktree', 'add', str(worktree)) + with worktree.as_cwd(): + cmd_output( + 'git', 'pull', '--no-rebase', 'origin', 'master', retcode=None, + ) + msg = f1_is_a_conflict_file.join('.git/worktrees/worktree/MERGE_MSG') + assert msg.exists() + test_merge_conflicts_git() From ccaa20da8db924b10b9c4f7c6948d1220dc0a968 Mon Sep 17 00:00:00 2001 From: Dennis Roche Date: Mon, 18 Oct 2021 20:57:55 +0800 Subject: [PATCH 195/334] all lower-case as requested --- .pre-commit-hooks.yaml | 124 ++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 646a0bb9..476b8ae8 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,193 +1,193 @@ - id: check-added-large-files - name: Check for added large files - description: Prevent giant files from being committed + name: check for added large files + description: prevent giant files from being committed entry: check-added-large-files language: python - id: check-ast - name: Check python ast - description: Simply check whether the files parse as valid python. + name: check python ast + description: simply check whether the files parse as valid python. entry: check-ast language: python types: [python] - id: check-byte-order-marker name: 'check BOM - deprecated: use fix-byte-order-marker' - description: forbid files which have a UTF-8 byte-order marker + description: forbid files which have a utf-8 byte-order marker entry: check-byte-order-marker language: python types: [text] - id: check-builtin-literals - name: Check builtin type constructor use - description: Require literal syntax when initializing empty or zero Python builtin types. + name: check builtin type constructor use + description: require literal syntax when initializing empty or zero python builtin types. entry: check-builtin-literals language: python types: [python] - id: check-case-conflict - name: Check for case conflicts - description: Check for files that would conflict in case-insensitive filesystems + name: check for case conflicts + description: check for files that would conflict in case-insensitive filesystems entry: check-case-conflict language: python - id: check-docstring-first - name: Check docstring is first - description: Checks a common error of defining a docstring after code. + name: check docstring is first + description: checks a common error of defining a docstring after code. entry: check-docstring-first language: python types: [python] - id: check-executables-have-shebangs - name: Check that executables have shebangs - description: Ensures that (non-binary) executables have a shebang. + name: check that executables have shebangs + description: ensures that (non-binary) executables have a shebang. entry: check-executables-have-shebangs language: python types: [text, executable] stages: [commit, push, manual] - id: check-json - name: Check JSON - description: This hook checks json files for parseable syntax. + name: check json + description: this hook checks json files for parseable syntax. entry: check-json language: python types: [json] - id: check-shebang-scripts-are-executable - name: Check that scripts with shebangs are executable - description: Ensures that (non-binary) files with a shebang are executable. + name: check that scripts with shebangs are executable + description: ensures that (non-binary) files with a shebang are executable. entry: check-shebang-scripts-are-executable language: python types: [text] stages: [commit, push, manual] - id: pretty-format-json - name: Pretty format JSON - description: This hook sets a standard for formatting JSON files. + name: pretty format json + description: this hook sets a standard for formatting json files. entry: pretty-format-json language: python types: [json] - id: check-merge-conflict - name: Check for merge conflicts - description: Check for files that contain merge conflict strings. + name: check for merge conflicts + description: check for files that contain merge conflict strings. entry: check-merge-conflict language: python types: [text] - id: check-symlinks - name: Check for broken symlinks - description: Checks for symlinks which do not point to anything. + name: check for broken symlinks + description: checks for symlinks which do not point to anything. entry: check-symlinks language: python types: [symlink] - id: check-toml - name: Check Toml - description: This hook checks toml files for parseable syntax. + name: check toml + description: this hook checks toml files for parseable syntax. entry: check-toml language: python types: [toml] - id: check-vcs-permalinks - name: Check vcs permalinks - description: Ensures that links to vcs websites are permalinks. + name: check vcs permalinks + description: ensures that links to vcs websites are permalinks. entry: check-vcs-permalinks language: python types: [text] - id: check-xml - name: Check Xml - description: This hook checks xml files for parseable syntax. + name: check xml + description: this hook checks xml files for parseable syntax. entry: check-xml language: python types: [xml] - id: check-yaml - name: Check Yaml - description: This hook checks yaml files for parseable syntax. + name: check yaml + description: this hook checks yaml files for parseable syntax. entry: check-yaml language: python types: [yaml] - id: debug-statements - name: Debug Statements (Python) - description: Check for debugger imports and py37+ `breakpoint()` calls in python source. + name: debug statements (python) + description: check for debugger imports and py37+ `breakpoint()` calls in python source. entry: debug-statement-hook language: python types: [python] - id: destroyed-symlinks - name: Detect Destroyed Symlinks - description: Detects symlinks which are changed to regular files with a content of a path which that symlink was pointing to. + name: detect destroyed symlinks + description: detects symlinks which are changed to regular files with a content of a path which that symlink was pointing to. entry: destroyed-symlinks language: python types: [file] - id: detect-aws-credentials - name: Detect AWS Credentials - description: Detects *your* aws credentials from the aws cli credentials file + name: detect aws credentials + description: detects *your* aws credentials from the aws cli credentials file entry: detect-aws-credentials language: python types: [text] - id: detect-private-key - name: Detect Private Key - description: Detects the presence of private keys + name: detect private key + description: detects the presence of private keys entry: detect-private-key language: python types: [text] - id: double-quote-string-fixer - name: Fix double quoted strings - description: This hook replaces double quoted strings with single quoted strings + name: fix double quoted strings + description: this hook replaces double quoted strings with single quoted strings entry: double-quote-string-fixer language: python types: [python] - id: end-of-file-fixer - name: Fix End of Files - description: Ensures that a file is either empty, or ends with one newline. + name: fix end of files + description: ensures that a file is either empty, or ends with one newline. entry: end-of-file-fixer language: python types: [text] stages: [commit, push, manual] - id: file-contents-sorter - name: File Contents Sorter - description: Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input in your .pre-commit-config.yaml file. + name: file contents sorter + description: sort the lines in specified files (defaults to alphabetical). you must provide list of target files as input in your .pre-commit-config.yaml file. entry: file-contents-sorter language: python files: '^$' - id: fix-byte-order-marker - name: fix UTF-8 byte order marker - description: removes UTF-8 byte order marker + name: fix utf-8 byte order marker + description: removes utf-8 byte order marker entry: fix-byte-order-marker language: python types: [text] - id: fix-encoding-pragma - name: Fix python encoding pragma + name: fix python encoding pragma language: python entry: fix-encoding-pragma - description: 'Add # -*- coding: utf-8 -*- to the top of python files' + description: 'add # -*- coding: utf-8 -*- to the top of python files' types: [python] - id: forbid-new-submodules - name: Forbid new submodules + name: forbid new submodules language: python entry: forbid-new-submodules - description: Prevent addition of new git submodules + description: prevent addition of new git submodules types: [directory] - id: mixed-line-ending - name: Mixed line ending - description: Replaces or checks mixed line ending + name: mixed line ending + description: replaces or checks mixed line ending entry: mixed-line-ending language: python types: [text] - id: name-tests-test - name: Tests should end in _test.py - description: This verifies that test files are named correctly + name: tests should end in _test.py + description: this verifies that test files are named correctly entry: name-tests-test language: python files: (^|/)tests/.+\.py$ - id: no-commit-to-branch - name: "Don't commit to branch" + name: "don't commit to branch" entry: no-commit-to-branch language: python pass_filenames: false always_run: true - id: requirements-txt-fixer - name: Fix requirements.txt - description: Sorts entries in requirements.txt + name: fix requirements.txt + description: sorts entries in requirements.txt entry: requirements-txt-fixer language: python files: requirements.*\.txt$ - id: sort-simple-yaml - name: Sort simple YAML files + name: sort simple yaml files language: python entry: sort-simple-yaml - description: Sorts simple YAML files which consist only of top-level keys, preserving comments and blocks. + description: sorts simple yaml files which consist only of top-level keys, preserving comments and blocks. files: '^$' - id: trailing-whitespace - name: Trim Trailing Whitespace - description: This hook trims trailing whitespace. + name: trim trailing whitespace + description: this hook trims trailing whitespace. entry: trailing-whitespace-fixer language: python types: [text] From 81c6c559e0c970bad2cbb98f5d0220a734f9d9db Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 18 Oct 2021 20:00:49 -0400 Subject: [PATCH 196/334] remove unneeded executable bits --- pre_commit_hooks/destroyed_symlinks.py | 0 pre_commit_hooks/sort_simple_yaml.py | 1 - 2 files changed, 1 deletion(-) mode change 100755 => 100644 pre_commit_hooks/destroyed_symlinks.py mode change 100755 => 100644 pre_commit_hooks/sort_simple_yaml.py diff --git a/pre_commit_hooks/destroyed_symlinks.py b/pre_commit_hooks/destroyed_symlinks.py old mode 100755 new mode 100644 diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py old mode 100755 new mode 100644 index 8ebc84ff..b267d7bf --- a/pre_commit_hooks/sort_simple_yaml.py +++ b/pre_commit_hooks/sort_simple_yaml.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python """Sort a simple YAML file, keeping blocks of comments and definitions together. From 2006a4d81b35aba28d04c27b990d8beda5f66def Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 20 Oct 2021 17:01:35 +0300 Subject: [PATCH 197/334] Fix inconsistent descriptions positions --- .pre-commit-hooks.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 476b8ae8..f2c307a0 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -145,15 +145,15 @@ types: [text] - id: fix-encoding-pragma name: fix python encoding pragma + description: 'add # -*- coding: utf-8 -*- to the top of python files' language: python entry: fix-encoding-pragma - description: 'add # -*- coding: utf-8 -*- to the top of python files' types: [python] - id: forbid-new-submodules name: forbid new submodules + description: prevent addition of new git submodules language: python entry: forbid-new-submodules - description: prevent addition of new git submodules types: [directory] - id: mixed-line-ending name: mixed line ending @@ -181,9 +181,9 @@ files: requirements.*\.txt$ - id: sort-simple-yaml name: sort simple yaml files + description: sorts simple yaml files which consist only of top-level keys, preserving comments and blocks. language: python entry: sort-simple-yaml - description: sorts simple yaml files which consist only of top-level keys, preserving comments and blocks. files: '^$' - id: trailing-whitespace name: trim trailing whitespace From 8a1d0fcbaa2eaa2345e085bec08f25353e0e3b00 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 20 Oct 2021 17:01:40 +0300 Subject: [PATCH 198/334] Fix inconsistent descriptions punctuations --- .pre-commit-hooks.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index f2c307a0..6ad1463d 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,6 +1,6 @@ - id: check-added-large-files name: check for added large files - description: prevent giant files from being committed + description: prevent giant files from being committed. entry: check-added-large-files language: python - id: check-ast @@ -11,7 +11,7 @@ types: [python] - id: check-byte-order-marker name: 'check BOM - deprecated: use fix-byte-order-marker' - description: forbid files which have a utf-8 byte-order marker + description: forbid files which have a utf-8 byte-order marker. entry: check-byte-order-marker language: python types: [text] @@ -23,7 +23,7 @@ types: [python] - id: check-case-conflict name: check for case conflicts - description: check for files that would conflict in case-insensitive filesystems + description: check for files that would conflict in case-insensitive filesystems. entry: check-case-conflict language: python - id: check-docstring-first @@ -108,19 +108,19 @@ types: [file] - id: detect-aws-credentials name: detect aws credentials - description: detects *your* aws credentials from the aws cli credentials file + description: detects *your* aws credentials from the aws cli credentials file. entry: detect-aws-credentials language: python types: [text] - id: detect-private-key name: detect private key - description: detects the presence of private keys + description: detects the presence of private keys. entry: detect-private-key language: python types: [text] - id: double-quote-string-fixer name: fix double quoted strings - description: this hook replaces double quoted strings with single quoted strings + description: this hook replaces double quoted strings with single quoted strings. entry: double-quote-string-fixer language: python types: [python] @@ -139,31 +139,31 @@ files: '^$' - id: fix-byte-order-marker name: fix utf-8 byte order marker - description: removes utf-8 byte order marker + description: removes utf-8 byte order marker. entry: fix-byte-order-marker language: python types: [text] - id: fix-encoding-pragma name: fix python encoding pragma - description: 'add # -*- coding: utf-8 -*- to the top of python files' + description: 'add # -*- coding: utf-8 -*- to the top of python files.' language: python entry: fix-encoding-pragma types: [python] - id: forbid-new-submodules name: forbid new submodules - description: prevent addition of new git submodules + description: prevent addition of new git submodules. language: python entry: forbid-new-submodules types: [directory] - id: mixed-line-ending name: mixed line ending - description: replaces or checks mixed line ending + description: replaces or checks mixed line ending. entry: mixed-line-ending language: python types: [text] - id: name-tests-test name: tests should end in _test.py - description: this verifies that test files are named correctly + description: this verifies that test files are named correctly. entry: name-tests-test language: python files: (^|/)tests/.+\.py$ @@ -175,7 +175,7 @@ always_run: true - id: requirements-txt-fixer name: fix requirements.txt - description: sorts entries in requirements.txt + description: sorts entries in requirements.txt. entry: requirements-txt-fixer language: python files: requirements.*\.txt$ From d7932b63a3c188323267030963c958b7a8c03380 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei <6d0847b9@opayq.com> Date: Tue, 27 Jul 2021 09:19:00 +0300 Subject: [PATCH 199/334] Fix inconsistent descriptions wording --- .pre-commit-hooks.yaml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 6ad1463d..56906603 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,29 +1,29 @@ - id: check-added-large-files name: check for added large files - description: prevent giant files from being committed. + description: prevents giant files from being committed. entry: check-added-large-files language: python - id: check-ast name: check python ast - description: simply check whether the files parse as valid python. + description: simply checks whether the files parse as valid python. entry: check-ast language: python types: [python] - id: check-byte-order-marker name: 'check BOM - deprecated: use fix-byte-order-marker' - description: forbid files which have a utf-8 byte-order marker. + description: forbids files which have a utf-8 byte-order marker. entry: check-byte-order-marker language: python types: [text] - id: check-builtin-literals name: check builtin type constructor use - description: require literal syntax when initializing empty or zero python builtin types. + description: requires literal syntax when initializing empty or zero python builtin types. entry: check-builtin-literals language: python types: [python] - id: check-case-conflict name: check for case conflicts - description: check for files that would conflict in case-insensitive filesystems. + description: checks for files that would conflict in case-insensitive filesystems. entry: check-case-conflict language: python - id: check-docstring-first @@ -41,7 +41,7 @@ stages: [commit, push, manual] - id: check-json name: check json - description: this hook checks json files for parseable syntax. + description: checks json files for parseable syntax. entry: check-json language: python types: [json] @@ -54,13 +54,13 @@ stages: [commit, push, manual] - id: pretty-format-json name: pretty format json - description: this hook sets a standard for formatting json files. + description: sets a standard for formatting json files. entry: pretty-format-json language: python types: [json] - id: check-merge-conflict name: check for merge conflicts - description: check for files that contain merge conflict strings. + description: checks for files that contain merge conflict strings. entry: check-merge-conflict language: python types: [text] @@ -72,7 +72,7 @@ types: [symlink] - id: check-toml name: check toml - description: this hook checks toml files for parseable syntax. + description: checks toml files for parseable syntax. entry: check-toml language: python types: [toml] @@ -84,19 +84,19 @@ types: [text] - id: check-xml name: check xml - description: this hook checks xml files for parseable syntax. + description: checks xml files for parseable syntax. entry: check-xml language: python types: [xml] - id: check-yaml name: check yaml - description: this hook checks yaml files for parseable syntax. + description: checks yaml files for parseable syntax. entry: check-yaml language: python types: [yaml] - id: debug-statements name: debug statements (python) - description: check for debugger imports and py37+ `breakpoint()` calls in python source. + description: checks for debugger imports and py37+ `breakpoint()` calls in python source. entry: debug-statement-hook language: python types: [python] @@ -120,7 +120,7 @@ types: [text] - id: double-quote-string-fixer name: fix double quoted strings - description: this hook replaces double quoted strings with single quoted strings. + description: replaces double quoted strings with single quoted strings. entry: double-quote-string-fixer language: python types: [python] @@ -133,7 +133,7 @@ stages: [commit, push, manual] - id: file-contents-sorter name: file contents sorter - description: sort the lines in specified files (defaults to alphabetical). you must provide list of target files as input in your .pre-commit-config.yaml file. + description: sorts the lines in specified files (defaults to alphabetical). you must provide list of target files as input in your .pre-commit-config.yaml file. entry: file-contents-sorter language: python files: '^$' @@ -145,13 +145,13 @@ types: [text] - id: fix-encoding-pragma name: fix python encoding pragma - description: 'add # -*- coding: utf-8 -*- to the top of python files.' + description: 'adds # -*- coding: utf-8 -*- to the top of python files.' language: python entry: fix-encoding-pragma types: [python] - id: forbid-new-submodules name: forbid new submodules - description: prevent addition of new git submodules. + description: prevents addition of new git submodules. language: python entry: forbid-new-submodules types: [directory] @@ -187,7 +187,7 @@ files: '^$' - id: trailing-whitespace name: trim trailing whitespace - description: this hook trims trailing whitespace. + description: trims trailing whitespace. entry: trailing-whitespace-fixer language: python types: [text] From 05a5297dbb55ba5d7b9c276ef1d02e648e5cfe46 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Sat, 23 Oct 2021 12:11:03 +0100 Subject: [PATCH 200/334] fix typos --- pre_commit_hooks/check_added_large_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index cb646d7b..e60f99c9 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -55,7 +55,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: ) parser.add_argument( '--maxkb', type=int, default=500, - help='Maxmimum allowable KB for added files', + help='Maximum allowable KB for added files', ) args = parser.parse_args(argv) From 39ab2ed85eb587ed3261189f31e5c0f191735bb8 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 23 Oct 2021 13:23:50 -0400 Subject: [PATCH 201/334] replace exit(main()) with raise SystemExit(main()) Committed via https://github.com/asottile/all-repos --- pre_commit_hooks/check_added_large_files.py | 2 +- pre_commit_hooks/check_ast.py | 2 +- pre_commit_hooks/check_builtin_literals.py | 2 +- pre_commit_hooks/check_byte_order_marker.py | 2 +- pre_commit_hooks/check_case_conflict.py | 2 +- pre_commit_hooks/check_executables_have_shebangs.py | 2 +- pre_commit_hooks/check_json.py | 2 +- pre_commit_hooks/check_merge_conflict.py | 2 +- pre_commit_hooks/check_shebang_scripts_are_executable.py | 2 +- pre_commit_hooks/check_symlinks.py | 2 +- pre_commit_hooks/check_toml.py | 2 +- pre_commit_hooks/check_vcs_permalinks.py | 2 +- pre_commit_hooks/check_xml.py | 2 +- pre_commit_hooks/check_yaml.py | 2 +- pre_commit_hooks/debug_statement_hook.py | 2 +- pre_commit_hooks/destroyed_symlinks.py | 2 +- pre_commit_hooks/detect_aws_credentials.py | 2 +- pre_commit_hooks/detect_private_key.py | 2 +- pre_commit_hooks/end_of_file_fixer.py | 2 +- pre_commit_hooks/file_contents_sorter.py | 2 +- pre_commit_hooks/fix_byte_order_marker.py | 2 +- pre_commit_hooks/fix_encoding_pragma.py | 2 +- pre_commit_hooks/forbid_new_submodules.py | 2 +- pre_commit_hooks/mixed_line_ending.py | 2 +- pre_commit_hooks/no_commit_to_branch.py | 2 +- pre_commit_hooks/pretty_format_json.py | 2 +- pre_commit_hooks/removed.py | 2 +- pre_commit_hooks/requirements_txt_fixer.py | 2 +- pre_commit_hooks/sort_simple_yaml.py | 2 +- pre_commit_hooks/string_fixer.py | 2 +- pre_commit_hooks/tests_should_end_in_test.py | 2 +- pre_commit_hooks/trailing_whitespace_fixer.py | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index e60f99c9..4eaf853d 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -67,4 +67,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_ast.py b/pre_commit_hooks/check_ast.py index 2be6e1af..ab5661dc 100644 --- a/pre_commit_hooks/check_ast.py +++ b/pre_commit_hooks/check_ast.py @@ -29,4 +29,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_builtin_literals.py b/pre_commit_hooks/check_builtin_literals.py index 6bcd8387..3fbae3e8 100644 --- a/pre_commit_hooks/check_builtin_literals.py +++ b/pre_commit_hooks/check_builtin_literals.py @@ -103,4 +103,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_byte_order_marker.py b/pre_commit_hooks/check_byte_order_marker.py index c0c2969c..fda05e84 100644 --- a/pre_commit_hooks/check_byte_order_marker.py +++ b/pre_commit_hooks/check_byte_order_marker.py @@ -20,4 +20,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py index 712b993f..c3f39db5 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -69,4 +69,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index e271c662..33f75c02 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -78,4 +78,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py index db589d01..96ba024e 100644 --- a/pre_commit_hooks/check_json.py +++ b/pre_commit_hooks/check_json.py @@ -37,4 +37,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index dc25b29a..aed1e9ca 100644 --- a/pre_commit_hooks/check_merge_conflict.py +++ b/pre_commit_hooks/check_merge_conflict.py @@ -51,4 +51,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_shebang_scripts_are_executable.py b/pre_commit_hooks/check_shebang_scripts_are_executable.py index dce8c59d..50bc9c0c 100644 --- a/pre_commit_hooks/check_shebang_scripts_are_executable.py +++ b/pre_commit_hooks/check_shebang_scripts_are_executable.py @@ -50,4 +50,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_symlinks.py b/pre_commit_hooks/check_symlinks.py index f014714a..db3b4fea 100644 --- a/pre_commit_hooks/check_symlinks.py +++ b/pre_commit_hooks/check_symlinks.py @@ -23,4 +23,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py index 87496753..f623e688 100644 --- a/pre_commit_hooks/check_toml.py +++ b/pre_commit_hooks/check_toml.py @@ -21,4 +21,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_vcs_permalinks.py b/pre_commit_hooks/check_vcs_permalinks.py index 5231d7af..1c77b9a3 100644 --- a/pre_commit_hooks/check_vcs_permalinks.py +++ b/pre_commit_hooks/check_vcs_permalinks.py @@ -57,4 +57,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py index 59b4d59e..0fa6bb23 100644 --- a/pre_commit_hooks/check_xml.py +++ b/pre_commit_hooks/check_xml.py @@ -22,4 +22,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 7453f6fb..5e86b73a 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -68,4 +68,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 0abac506..f78d6d62 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -82,4 +82,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/destroyed_symlinks.py b/pre_commit_hooks/destroyed_symlinks.py index cfaf4e53..a3f122ff 100644 --- a/pre_commit_hooks/destroyed_symlinks.py +++ b/pre_commit_hooks/destroyed_symlinks.py @@ -93,4 +93,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index 1663cfd6..ba1d789a 100644 --- a/pre_commit_hooks/detect_aws_credentials.py +++ b/pre_commit_hooks/detect_aws_credentials.py @@ -149,4 +149,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/detect_private_key.py b/pre_commit_hooks/detect_private_key.py index 3a6027da..18f95394 100644 --- a/pre_commit_hooks/detect_private_key.py +++ b/pre_commit_hooks/detect_private_key.py @@ -38,4 +38,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/end_of_file_fixer.py b/pre_commit_hooks/end_of_file_fixer.py index 1c07379d..40e8821d 100644 --- a/pre_commit_hooks/end_of_file_fixer.py +++ b/pre_commit_hooks/end_of_file_fixer.py @@ -67,4 +67,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index ebbcd206..392e2261 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -81,4 +81,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/fix_byte_order_marker.py b/pre_commit_hooks/fix_byte_order_marker.py index 1ffe047d..51b94e16 100644 --- a/pre_commit_hooks/fix_byte_order_marker.py +++ b/pre_commit_hooks/fix_byte_order_marker.py @@ -27,4 +27,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index 88d72ed7..c704774f 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -145,4 +145,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/forbid_new_submodules.py b/pre_commit_hooks/forbid_new_submodules.py index 9d1aa2f5..02758089 100644 --- a/pre_commit_hooks/forbid_new_submodules.py +++ b/pre_commit_hooks/forbid_new_submodules.py @@ -44,4 +44,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/mixed_line_ending.py b/pre_commit_hooks/mixed_line_ending.py index 0ef8e2c0..4e07ed96 100644 --- a/pre_commit_hooks/mixed_line_ending.py +++ b/pre_commit_hooks/mixed_line_ending.py @@ -85,4 +85,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index 49ffecf7..db848507 100644 --- a/pre_commit_hooks/no_commit_to_branch.py +++ b/pre_commit_hooks/no_commit_to_branch.py @@ -44,4 +44,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 61b01698..33ad5a1c 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -132,4 +132,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/removed.py b/pre_commit_hooks/removed.py index 60df0963..236cbf83 100644 --- a/pre_commit_hooks/removed.py +++ b/pre_commit_hooks/removed.py @@ -12,4 +12,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 351e5b15..63f891f7 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -150,4 +150,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py index b267d7bf..39f683e4 100644 --- a/pre_commit_hooks/sort_simple_yaml.py +++ b/pre_commit_hooks/sort_simple_yaml.py @@ -122,4 +122,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py index 3fdb6e2f..a08a5f76 100644 --- a/pre_commit_hooks/string_fixer.py +++ b/pre_commit_hooks/string_fixer.py @@ -77,4 +77,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py index b8cf9152..bffb0c42 100644 --- a/pre_commit_hooks/tests_should_end_in_test.py +++ b/pre_commit_hooks/tests_should_end_in_test.py @@ -30,4 +30,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) diff --git a/pre_commit_hooks/trailing_whitespace_fixer.py b/pre_commit_hooks/trailing_whitespace_fixer.py index 05ed9994..82faa2dc 100644 --- a/pre_commit_hooks/trailing_whitespace_fixer.py +++ b/pre_commit_hooks/trailing_whitespace_fixer.py @@ -99,4 +99,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int: if __name__ == '__main__': - exit(main()) + raise SystemExit(main()) From d750167495ce904ebc44e29d71b723648f8c748d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Oct 2021 18:58:08 +0000 Subject: [PATCH 202/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/add-trailing-comma: v2.1.0 → v2.2.0](https://github.com/asottile/add-trailing-comma/compare/v2.1.0...v2.2.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4c42d392..76a886cc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.1.0 + rev: v2.2.0 hooks: - id: add-trailing-comma args: [--py36-plus] From bdcfb09762178dda10999c4ce60f2bb92810e06f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Nov 2021 19:35:41 +0000 Subject: [PATCH 203/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v1.18.0 → v1.19.0](https://github.com/asottile/setup-cfg-fmt/compare/v1.18.0...v1.19.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 76a886cc..3cfd5f3a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.18.0 + rev: v1.19.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy From f4749f2fbb07c26fa6650c287d11342b01b40aa8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:51:54 +0000 Subject: [PATCH 204/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.29.0 → v2.29.1](https://github.com/asottile/pyupgrade/compare/v2.29.0...v2.29.1) - [github.com/asottile/add-trailing-comma: v2.2.0 → v2.2.1](https://github.com/asottile/add-trailing-comma/compare/v2.2.0...v2.2.1) - [github.com/asottile/setup-cfg-fmt: v1.19.0 → v1.20.0](https://github.com/asottile/setup-cfg-fmt/compare/v1.19.0...v1.20.0) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3cfd5f3a..3596edc2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,17 +27,17 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.29.0 + rev: v2.29.1 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.2.0 + rev: v2.2.1 hooks: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.19.0 + rev: v1.20.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy From 60c1d8e12f4a8985003ee686a1b36deeebcf6a43 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 23 Nov 2021 11:24:38 -0500 Subject: [PATCH 205/334] Use org-default .github/FUNDING.yml Committed via https://github.com/asottile/all-repos --- .github/FUNDING.yml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 9408e44d..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -github: asottile -open_collective: pre-commit From 16bc739ce722fe218ebe54b758a8dc46a4745984 Mon Sep 17 00:00:00 2001 From: Pujit Mehrotra Date: Fri, 19 Nov 2021 12:13:37 -0500 Subject: [PATCH 206/334] Suggest usable call when exec files lack shebang on Windows Resolves Issue #686 --- pre_commit_hooks/check_executables_have_shebangs.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index 33f75c02..34af5cac 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -64,6 +64,8 @@ def _message(path: str) -> None: f'{path}: marked executable but has no (or invalid) shebang!\n' f" If it isn't supposed to be executable, try: " f'`chmod -x {shlex.quote(path)}`\n' + f' If on Windows, you may also need to: ' + f'`git add --chmod=-x {shlex.quote(path)}`\n' f' If it is supposed to be executable, double-check its shebang.', file=sys.stderr, ) From 77a394ea413d077c2d7fd63f461ce5a49c39518a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Dec 2021 19:41:59 +0000 Subject: [PATCH 207/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.910-1 → v0.920](https://github.com/pre-commit/mirrors-mypy/compare/v0.910-1...v0.920) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3596edc2..ae5bcffb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.910-1 + rev: v0.920 hooks: - id: mypy additional_dependencies: [types-all] From 03a65ca35757ed7baf4c02474840d7dcbda5495a Mon Sep 17 00:00:00 2001 From: Alex Martani Date: Thu, 21 Oct 2021 15:29:54 -0700 Subject: [PATCH 208/334] Fix check-added-large-files --enforce-all to correctly consider all git-lfs files. `git lfs status` only outputs status for files that are pending some git-lfs related operation. For usage with --enforce-all, we need the list of all files that are tracked, which can be achived by `git lfs ls-files`. Fixes: https://github.com/pre-commit/pre-commit-hooks/issues/560 --- pre_commit_hooks/check_added_large_files.py | 33 ++++++++++++++------- tests/check_added_large_files_test.py | 13 ++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index 4eaf853d..e1beb4ef 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -1,24 +1,33 @@ import argparse -import json 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 CalledProcessError -from pre_commit_hooks.util import cmd_output +from pre_commit_hooks.util import zsplit -def lfs_files() -> Set[str]: - try: - # Introduced in git-lfs 2.2.0, first working in 2.2.1 - lfs_ret = cmd_output('git', 'lfs', 'status', '--json') - except CalledProcessError: # pragma: no cover (with git-lfs) - lfs_ret = '{"files":{}}' +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 - return set(json.loads(lfs_ret)['files']) + check_attr = subprocess.run( + ('git', 'check-attr', 'filter', '-z', '--stdin'), + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + encoding='utf-8', + check=True, + input='\0'.join(filenames), + ) + stdout = zsplit(check_attr.stdout) + for i in range(0, len(stdout), 3): + filename, filter_tag = stdout[i], stdout[i + 2] + if filter_tag == 'lfs': + filenames.remove(filename) def find_large_added_files( @@ -30,7 +39,9 @@ def find_large_added_files( # Find all added files that are also in the list of files pre-commit tells # us about retv = 0 - filenames_filtered = set(filenames) - lfs_files() + filenames_filtered = set(filenames) + filter_lfs_files(filenames_filtered) + if not enforce_all: filenames_filtered &= added_files() diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index d38c4f67..5d2239ba 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -121,3 +121,16 @@ def test_enforce_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover cmd_output('git', 'add', '--', '.') # With --enforce-all large files on git lfs should succeed assert main(('--enforce-all', '--maxkb', '9', 'f.py')) == 0 + + +@xfailif_no_gitlfs # pragma: no cover +def test_enforce_allows_gitlfs_after_commit(temp_git_dir, monkeypatch): + with temp_git_dir.as_cwd(): + monkeypatch.setenv('HOME', str(temp_git_dir)) + cmd_output('git', 'lfs', 'install') + temp_git_dir.join('f.py').write('a' * 10000) + cmd_output('git', 'lfs', 'track', 'f.py') + cmd_output('git', 'add', '--', '.') + git_commit('-am', 'foo') + # With --enforce-all large files on git lfs should succeed + assert main(('--enforce-all', '--maxkb', '9', 'f.py')) == 0 From 91ee010907d8cab64a74818500cc352382b63465 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 20 Dec 2021 23:09:53 -0500 Subject: [PATCH 209/334] remove need for monkeypatching home --- tests/check_added_large_files_test.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/check_added_large_files_test.py b/tests/check_added_large_files_test.py index 5d2239ba..c16bf5a9 100644 --- a/tests/check_added_large_files_test.py +++ b/tests/check_added_large_files_test.py @@ -85,10 +85,9 @@ def has_gitlfs(): @xfailif_no_gitlfs -def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover +def test_allows_gitlfs(temp_git_dir): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv('HOME', str(temp_git_dir)) - cmd_output('git', 'lfs', 'install') + cmd_output('git', 'lfs', 'install', '--local') temp_git_dir.join('f.py').write('a' * 10000) cmd_output('git', 'lfs', 'track', 'f.py') cmd_output('git', 'add', '--', '.') @@ -97,10 +96,9 @@ def test_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover @xfailif_no_gitlfs -def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover +def test_moves_with_gitlfs(temp_git_dir): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv('HOME', str(temp_git_dir)) - cmd_output('git', 'lfs', 'install') + cmd_output('git', 'lfs', 'install', '--local') cmd_output('git', 'lfs', 'track', 'a.bin', 'b.bin') # First add the file we're going to move temp_git_dir.join('a.bin').write('a' * 10000) @@ -112,10 +110,9 @@ def test_moves_with_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover @xfailif_no_gitlfs -def test_enforce_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover +def test_enforce_allows_gitlfs(temp_git_dir): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv('HOME', str(temp_git_dir)) - cmd_output('git', 'lfs', 'install') + cmd_output('git', 'lfs', 'install', '--local') temp_git_dir.join('f.py').write('a' * 10000) cmd_output('git', 'lfs', 'track', 'f.py') cmd_output('git', 'add', '--', '.') @@ -123,11 +120,10 @@ def test_enforce_allows_gitlfs(temp_git_dir, monkeypatch): # pragma: no cover assert main(('--enforce-all', '--maxkb', '9', 'f.py')) == 0 -@xfailif_no_gitlfs # pragma: no cover -def test_enforce_allows_gitlfs_after_commit(temp_git_dir, monkeypatch): +@xfailif_no_gitlfs +def test_enforce_allows_gitlfs_after_commit(temp_git_dir): # pragma: no cover with temp_git_dir.as_cwd(): - monkeypatch.setenv('HOME', str(temp_git_dir)) - cmd_output('git', 'lfs', 'install') + cmd_output('git', 'lfs', 'install', '--local') temp_git_dir.join('f.py').write('a' * 10000) cmd_output('git', 'lfs', 'track', 'f.py') cmd_output('git', 'add', '--', '.') From 8fe62d14e0b4d7d845a7022c5c2c3ae41bdd3f26 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 23 Dec 2021 23:47:17 -0500 Subject: [PATCH 210/334] v4.1.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ae5bcffb..4639bc6b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.1.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 530c4c8d..50e72022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +4.1.0 - 2021-12-22 +================== + +### Features +- `debug-statements`: add `pdbr` debugger. + - #614 PR by @cansarigol. +- `detect-private-key`: add detection for additional key types. + - #658 PR by @ljmf00. +- `check-executables-have-shebangs`: improve messaging on windows. + - #689 PR by @pujitm. + - #686 issue by @jmerdich. +- `check-added-large-files`: support `--enforce-all` with `git-lfs`. + - #674 PR by @amartani. + - #560 issue by @jeremy-coulon. + +### Fixes +- `check-case-conflict`: improve performance. + - #626 PR by @guykisel. + - #625 issue by @guykisel. +- `forbid-new-submodules`: fix false-negatives for `pre-push`. + - #619 PR by @m-khvoinitsky. + - #609 issue by @m-khvoinitsky. +- `check-merge-conflict`: fix execution in git worktrees. + - #662 PR by @errsyn. + - #638 issue by @daschuer. + +### Misc. +- Normalize case of hook names and descriptions. + - #671 PR by @dennisroche. + - #673 PR by @revolter. + 4.0.1 - 2021-05-16 ================== diff --git a/README.md b/README.md index 7486aba2..c5a199e1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 # Use the ref you want to point at + rev: v4.1.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 890d6295..45498ebe 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.0.1 +version = 4.1.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 8171601b9643dc6ebef21f690d42fb53e79f04f4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 20:06:27 +0000 Subject: [PATCH 211/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.920 → v0.930](https://github.com/pre-commit/mirrors-mypy/compare/v0.920...v0.930) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4639bc6b..47754449 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.920 + rev: v0.930 hooks: - id: mypy additional_dependencies: [types-all] From 3b8bfd7d0ebb07fd942449b93dba70ef12734ea1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Jan 2022 20:02:30 +0000 Subject: [PATCH 212/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-autopep8: v1.5.7 → v1.6.0](https://github.com/pre-commit/mirrors-autopep8/compare/v1.5.7...v1.6.0) - [github.com/asottile/pyupgrade: v2.29.1 → v2.31.0](https://github.com/asottile/pyupgrade/compare/v2.29.1...v2.31.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47754449..ba7db054 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: flake8 additional_dependencies: [flake8-typing-imports==1.7.0] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.5.7 + rev: v1.6.0 hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports @@ -27,7 +27,7 @@ repos: - id: reorder-python-imports args: [--py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.29.1 + rev: v2.31.0 hooks: - id: pyupgrade args: [--py36-plus] From 879055f991f96e623e2eb82ff7bee7f48f3721fc Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 6 Jan 2022 16:33:18 -0500 Subject: [PATCH 213/334] update display name of `name-tests-test` --- .pre-commit-hooks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 56906603..9e835d58 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -162,7 +162,7 @@ language: python types: [text] - id: name-tests-test - name: tests should end in _test.py + name: python tests naming description: this verifies that test files are named correctly. entry: name-tests-test language: python From ef9755e0a1c05d10fece252cab5234defbca404c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 8 Jan 2022 14:14:39 -0500 Subject: [PATCH 214/334] remove --fail-under from tox (covdefaults handles this) Committed via https://github.com/asottile/all-repos --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 965eba92..790ce7f7 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ setenv = commands = coverage erase coverage run -m pytest {posargs:tests} - coverage report --fail-under 100 + coverage report [testenv:pre-commit] skip_install = true From 21350a2362b0703e5bbce10dfac08c8da7f22eb9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Jan 2022 20:21:46 +0000 Subject: [PATCH 215/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.930 → v0.931](https://github.com/pre-commit/mirrors-mypy/compare/v0.930...v0.931) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ba7db054..d5d47780 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.930 + rev: v0.931 hooks: - id: mypy additional_dependencies: [types-all] From 8f6152921e65fe1a82bc475cafb721bd525ba5df Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 15 Jan 2022 19:24:05 -0500 Subject: [PATCH 216/334] drop python3.6 support python 3.6 reached end of life on 2021-12-23 Committed via https://github.com/asottile/all-repos --- .pre-commit-config.yaml | 4 ++-- azure-pipelines.yml | 4 ++-- pre_commit_hooks/check_added_large_files.py | 8 ++++---- pre_commit_hooks/check_ast.py | 5 +++-- pre_commit_hooks/check_builtin_literals.py | 17 ++++++++--------- pre_commit_hooks/check_byte_order_marker.py | 5 +++-- pre_commit_hooks/check_case_conflict.py | 10 +++++----- pre_commit_hooks/check_docstring_first.py | 5 +++-- .../check_executables_have_shebangs.py | 11 +++++------ pre_commit_hooks/check_json.py | 12 +++++------- pre_commit_hooks/check_merge_conflict.py | 5 +++-- .../check_shebang_scripts_are_executable.py | 11 +++++------ pre_commit_hooks/check_symlinks.py | 5 +++-- pre_commit_hooks/check_toml.py | 5 +++-- pre_commit_hooks/check_vcs_permalinks.py | 8 ++++---- pre_commit_hooks/check_xml.py | 5 +++-- pre_commit_hooks/check_yaml.py | 5 +++-- pre_commit_hooks/debug_statement_hook.py | 8 ++++---- pre_commit_hooks/destroyed_symlinks.py | 10 +++++----- pre_commit_hooks/detect_aws_credentials.py | 19 +++++++++---------- pre_commit_hooks/detect_private_key.py | 5 +++-- pre_commit_hooks/end_of_file_fixer.py | 5 +++-- pre_commit_hooks/file_contents_sorter.py | 7 ++++--- pre_commit_hooks/fix_byte_order_marker.py | 5 +++-- pre_commit_hooks/fix_encoding_pragma.py | 9 +++++---- pre_commit_hooks/forbid_new_submodules.py | 5 +++-- pre_commit_hooks/mixed_line_ending.py | 8 ++++---- pre_commit_hooks/no_commit_to_branch.py | 5 +++-- pre_commit_hooks/pretty_format_json.py | 14 ++++++-------- pre_commit_hooks/removed.py | 5 +++-- pre_commit_hooks/requirements_txt_fixer.py | 16 ++++++++-------- pre_commit_hooks/sort_simple_yaml.py | 14 +++++++------- pre_commit_hooks/string_fixer.py | 8 ++++---- pre_commit_hooks/tests_should_end_in_test.py | 5 +++-- pre_commit_hooks/trailing_whitespace_fixer.py | 9 +++++---- pre_commit_hooks/util.py | 11 +++++------ setup.cfg | 3 +-- setup.py | 2 ++ testing/util.py | 2 ++ tests/check_added_large_files_test.py | 2 ++ tests/check_ast_test.py | 2 ++ tests/check_builtin_literals_test.py | 2 ++ tests/check_byte_order_marker_test.py | 2 ++ tests/check_case_conflict_test.py | 2 ++ tests/check_docstring_first_test.py | 2 ++ tests/check_executables_have_shebangs_test.py | 2 ++ tests/check_json_test.py | 2 ++ tests/check_merge_conflict_test.py | 2 ++ ...eck_shebang_scripts_are_executable_test.py | 2 ++ tests/check_symlinks_test.py | 2 ++ tests/check_toml_test.py | 2 ++ tests/check_vcs_permalinks_test.py | 2 ++ tests/check_xml_test.py | 2 ++ tests/check_yaml_test.py | 2 ++ tests/conftest.py | 2 ++ tests/debug_statement_hook_test.py | 2 ++ tests/destroyed_symlinks_test.py | 2 ++ tests/detect_aws_credentials_test.py | 2 ++ tests/detect_private_key_test.py | 2 ++ tests/end_of_file_fixer_test.py | 2 ++ tests/file_contents_sorter_test.py | 2 ++ tests/fix_byte_order_marker_test.py | 2 ++ tests/fix_encoding_pragma_test.py | 2 ++ tests/forbid_new_submodules_test.py | 2 ++ tests/mixed_line_ending_test.py | 2 ++ tests/no_commit_to_branch_test.py | 2 ++ tests/pretty_format_json_test.py | 2 ++ tests/readme_test.py | 2 ++ tests/removed_test.py | 2 ++ tests/requirements_txt_fixer_test.py | 2 ++ tests/sort_simple_yaml_test.py | 2 ++ tests/string_fixer_test.py | 2 ++ tests/tests_should_end_in_test_test.py | 2 ++ tests/trailing_whitespace_fixer_test.py | 2 ++ tests/util_test.py | 2 ++ tox.ini | 2 +- 76 files changed, 229 insertions(+), 145 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d5d47780..4b496005 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 58dc61dd..d54596e3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -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 diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index e1beb4ef..79c8d4e3 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 @@ 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='*', diff --git a/pre_commit_hooks/check_ast.py b/pre_commit_hooks/check_ast.py index ab5661dc..fdac3617 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 3fbae3e8..d3054aa0 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 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 @@ def visit_Call(self, node: ast.Call) -> None: 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()) diff --git a/pre_commit_hooks/check_byte_order_marker.py b/pre_commit_hooks/check_byte_order_marker.py index fda05e84..59cc5612 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 c3f39db5..33a13f1b 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 @@ 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='*', diff --git a/pre_commit_hooks/check_docstring_first.py b/pre_commit_hooks/check_docstring_first.py index 875c0fba..1744919c 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 @@ def check_docstring_first(src: bytes, 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='*') 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 34af5cac..6b5402ac 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 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) diff --git a/pre_commit_hooks/check_json.py b/pre_commit_hooks/check_json.py index 96ba024e..6a679fee 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 @@ 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) diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index aed1e9ca..22031a29 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 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') diff --git a/pre_commit_hooks/check_shebang_scripts_are_executable.py b/pre_commit_hooks/check_shebang_scripts_are_executable.py index 50bc9c0c..0f35650b 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_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) diff --git a/pre_commit_hooks/check_symlinks.py b/pre_commit_hooks/check_symlinks.py index db3b4fea..a85c82a1 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 f623e688..88f70865 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 1c77b9a3..68639bd9 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 @@ 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( diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py index 0fa6bb23..c256af9b 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 5e86b73a..250794ef 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 @@ class Key(NamedTuple): } -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 f78d6d62..00b67983 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 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) diff --git a/pre_commit_hooks/destroyed_symlinks.py b/pre_commit_hooks/destroyed_symlinks.py index a3f122ff..88253c0b 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 @@ 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) diff --git a/pre_commit_hooks/detect_aws_credentials.py b/pre_commit_hooks/detect_aws_credentials.py index ba1d789a..4f59d9cf 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 @@ 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) diff --git a/pre_commit_hooks/detect_private_key.py b/pre_commit_hooks/detect_private_key.py index 18f95394..cd51f901 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 40e8821d..a30dce92 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 @@ 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) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 392e2261..c5691f0b 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 @@ 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( diff --git a/pre_commit_hooks/fix_byte_order_marker.py b/pre_commit_hooks/fix_byte_order_marker.py index 51b94e16..22a49909 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 c704774f..60c71eeb 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 @@ 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', ) diff --git a/pre_commit_hooks/forbid_new_submodules.py b/pre_commit_hooks/forbid_new_submodules.py index 02758089..b806cad2 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 4e07ed96..0328e865 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 @@ 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', diff --git a/pre_commit_hooks/no_commit_to_branch.py b/pre_commit_hooks/no_commit_to_branch.py index db848507..741f7267 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 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', diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 33ad5a1c..627a11cc 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 @@ 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', diff --git a/pre_commit_hooks/removed.py b/pre_commit_hooks/removed.py index 236cbf83..6f6c7b72 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 63f891f7..58843940 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 @@ 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 @@ def name(self) -> bytes: 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 append_value(self, value: bytes) -> None: 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) diff --git a/pre_commit_hooks/sort_simple_yaml.py b/pre_commit_hooks/sort_simple_yaml.py index 39f683e4..116b5c19 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 @@ 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) diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py index a08a5f76..0ef9bc7a 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 @@ 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) diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py index bffb0c42..e1ffe367 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 82faa2dc..84f50671 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 _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', diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py index 402e33e6..d6c90ae0 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 @@ 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') diff --git a/setup.cfg b/setup.cfg index 45498ebe..5b0f7ca5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 = diff --git a/setup.py b/setup.py index 8bf1ba93..3d93aefb 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 50437544..2bbbe644 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 c16bf5a9..54c4e689 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 686fd116..62439661 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 e9367989..1b182573 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 4c402476..909a39bb 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 d9211b57..a914f452 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 ed5c08ef..079896f1 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 5703eded..82d03e3d 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 3ec67f1c..53e1f52d 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 79c1b118..d3322db1 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 9e78b06c..e4bd07ca 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 07c11687..e2c2c78f 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 c7251eb0..d594f815 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 ad591515..01ce94de 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 357bad64..767619f1 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 1a017a12..54eb16e8 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 f92cfc18..807f15b8 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 428421a0..349fe89c 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 cde06cfb..39c474a1 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 72125099..afda47a9 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 d2c724f0..41f8bae5 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 60b9e82f..8a5d889e 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 15f11342..5e79e401 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 da150e37..d7a65990 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 f3afa094..98557e98 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 0326d941..058a3294 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 f1c26418..a7e79719 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 9fcb5808..eaae5e62 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 7fda23b3..5ded724a 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 7df7fcfe..038868d8 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 d635eb1e..cd669578 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 e3c6ed50..b725afa2 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 a682c158..6cbda857 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 6ddb0ac8..9dd73152 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 4df2963f..dc3744b8 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 bb3b62d4..c07497a2 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 7f488161..92473e59 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 790ce7f7..cb2b92ab 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 From c823ddba6f064e1342739f5150b7825073fc90a5 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 23 Jan 2022 21:21:12 -0500 Subject: [PATCH 217/334] upgrade flake8-typing-imports Committed via https://github.com/asottile/all-repos --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b496005..8a7b9f4d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: rev: 4.0.1 hooks: - id: flake8 - additional_dependencies: [flake8-typing-imports==1.7.0] + additional_dependencies: [flake8-typing-imports==1.12.0] - repo: https://github.com/pre-commit/mirrors-autopep8 rev: v1.6.0 hooks: From 2fa82e87c6a910e3f31819a1c4228a6eb0eca365 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 31 Jan 2022 21:02:45 +0000 Subject: [PATCH 218/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v2.6.0 → v2.7.1](https://github.com/asottile/reorder_python_imports/compare/v2.6.0...v2.7.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8a7b9f4d..babaa896 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports - rev: v2.6.0 + rev: v2.7.1 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] From e7cf495decb99b396b322db5aad275af9a218267 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 21 Feb 2022 18:44:06 +0200 Subject: [PATCH 219/334] Document file-contents-sorter arguments Re: https://github.com/pre-commit/pre-commit-hooks/blob/40cc31b02ceb72045509576e51d9c82503751422/pre_commit_hooks/file_contents_sorter.py#L54-L65 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c5a199e1..0bf57516 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,10 @@ Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. Note that this hook WILL remove blank lines and does NOT respect any comments. +The following arguments are available: +- `--ignore-case` - fold lower case to upper case characters. +- `--unique` - ensure each line is unique. + #### `forbid-new-submodules` Prevent addition of new git submodules. From 84e93fcbb5dc9f1c824d519413ac40c02b97b65b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 13 Mar 2022 19:55:42 -0400 Subject: [PATCH 220/334] remove unneeded gitignore lines - coverage-html: coverage>=6.2 writes a .gitignore file - mypy_cache: mypy>=0.770 writes a .gitignore file - pytest_cache: pytest>=3.8.1 writes a .gitignore file - venv: virtualenv>=20.0.21 writes a .gitignore file Committed via https://github.com/asottile/all-repos --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitignore b/.gitignore index 32c2fec0..4f6c5b7c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,4 @@ .*.sw[a-z] .coverage .tox -.venv.touch -/.mypy_cache -/.pytest_cache -/venv* -coverage-html dist From aabb4777dd6aa3e0ca4f52b2301d13aeb509a12a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:18:05 +0000 Subject: [PATCH 221/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v2.7.1 → v3.0.1](https://github.com/asottile/reorder_python_imports/compare/v2.7.1...v3.0.1) - [github.com/asottile/pyupgrade: v2.31.0 → v2.31.1](https://github.com/asottile/pyupgrade/compare/v2.31.0...v2.31.1) - [github.com/pre-commit/mirrors-mypy: v0.931 → v0.940](https://github.com/pre-commit/mirrors-mypy/compare/v0.931...v0.940) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index babaa896..cfbf0e76 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,12 +22,12 @@ repos: hooks: - id: autopep8 - repo: https://github.com/asottile/reorder_python_imports - rev: v2.7.1 + rev: v3.0.1 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/pyupgrade - rev: v2.31.0 + rev: v2.31.1 hooks: - id: pyupgrade args: [--py37-plus] @@ -41,7 +41,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.931 + rev: v0.940 hooks: - id: mypy additional_dependencies: [types-all] From 30609f1b6d4b888c2b5047c355b7bb62f0220d52 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 22:31:27 +0000 Subject: [PATCH 222/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.940 → v0.941](https://github.com/pre-commit/mirrors-mypy/compare/v0.940...v0.941) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cfbf0e76..6c1f591f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.940 + rev: v0.941 hooks: - id: mypy additional_dependencies: [types-all] From 202ec6b8f5caebaa97c5f6db0c2a7723df592ed9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 24 Mar 2022 14:53:14 -0400 Subject: [PATCH 223/334] Update default branch to main Committed via https://github.com/asottile/all-repos --- README.md | 10 +++++----- azure-pipelines.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0bf57516..63212d14 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![Build Status](https://asottile.visualstudio.com/asottile/_apis/build/status/pre-commit.pre-commit-hooks?branchName=master)](https://asottile.visualstudio.com/asottile/_build/latest?definitionId=17&branchName=master) -[![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/asottile/asottile/17/master.svg)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=17&branchName=master) -[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pre-commit/pre-commit-hooks/master.svg)](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit-hooks/master) +[![Build Status](https://asottile.visualstudio.com/asottile/_apis/build/status/pre-commit.pre-commit-hooks?branchName=main)](https://asottile.visualstudio.com/asottile/_build/latest?definitionId=17&branchName=main) +[![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/asottile/asottile/17/main.svg)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=17&branchName=main) +[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pre-commit/pre-commit-hooks/main.svg)](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit-hooks/main) pre-commit-hooks ================ @@ -146,8 +146,8 @@ Assert that files in tests/ end in `_test.py`. #### `no-commit-to-branch` Protect specific branches from direct checkins. - - Use `args: [--branch, staging, --branch, master]` to set the branch. - Both `master` and `main` are protected by default if no branch argument is set. + - Use `args: [--branch, staging, --branch, main]` to set the branch. + Both `main` and `master` are protected by default if no branch argument is set. - `-b` / `--branch` may be specified multiple times to protect multiple branches. - `-p` / `--pattern` can be used to protect branches that match a supplied regex diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d54596e3..117b014f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,6 +1,6 @@ trigger: branches: - include: [master, test-me-*] + include: [main, test-me-*] tags: include: ['*'] From 1e48e904a828f77a6e8c41ae2e703853276f357a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Fri, 25 Mar 2022 14:12:21 -0400 Subject: [PATCH 224/334] reorder pre-commit config Committed via https://github.com/asottile/all-repos --- .pre-commit-config.yaml | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6c1f591f..6f1fafd2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,44 +4,40 @@ repos: hooks: - id: trailing-whitespace - id: end-of-file-fixer - - id: check-docstring-first - - id: check-json - - id: check-added-large-files - id: check-yaml - id: debug-statements - - id: name-tests-test - id: double-quote-string-fixer + - id: name-tests-test - id: requirements-txt-fixer -- repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 - hooks: - - id: flake8 - additional_dependencies: [flake8-typing-imports==1.12.0] -- repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.6.0 +- repo: https://github.com/asottile/setup-cfg-fmt + rev: v1.20.0 hooks: - - id: autopep8 + - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports rev: v3.0.1 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] +- repo: https://github.com/asottile/add-trailing-comma + rev: v2.2.1 + hooks: + - id: add-trailing-comma + args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade rev: v2.31.1 hooks: - id: pyupgrade args: [--py37-plus] -- repo: https://github.com/asottile/add-trailing-comma - rev: v2.2.1 +- repo: https://github.com/pre-commit/mirrors-autopep8 + rev: v1.6.0 hooks: - - id: add-trailing-comma - args: [--py36-plus] -- repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.20.0 + - id: autopep8 +- repo: https://github.com/PyCQA/flake8 + rev: 4.0.1 hooks: - - id: setup-cfg-fmt + - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.941 + rev: v0.942 hooks: - id: mypy additional_dependencies: [types-all] From a9b21c267c86b0c8f5914c4820f7312be64cc71a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Apr 2022 19:59:47 +0000 Subject: [PATCH 225/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v1.20.0 → v1.20.1](https://github.com/asottile/setup-cfg-fmt/compare/v1.20.0...v1.20.1) - [github.com/asottile/add-trailing-comma: v2.2.1 → v2.2.2](https://github.com/asottile/add-trailing-comma/compare/v2.2.1...v2.2.2) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6f1fafd2..c7edbe96 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.20.0 + rev: v1.20.1 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports @@ -19,7 +19,7 @@ repos: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.2.1 + rev: v2.2.2 hooks: - id: add-trailing-comma args: [--py36-plus] From b13ff9b8681d39e6581ce8327d02ce906f022948 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 6 Apr 2022 16:55:26 -0400 Subject: [PATCH 226/334] adjust error outputs to be more standardized --- pre_commit_hooks/check_docstring_first.py | 4 ++-- pre_commit_hooks/check_merge_conflict.py | 7 ++++--- pre_commit_hooks/debug_statement_hook.py | 2 +- tests/check_docstring_first_test.py | 6 +++--- tests/check_merge_conflict_test.py | 12 +++++++++--- tests/debug_statement_hook_test.py | 4 +++- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/pre_commit_hooks/check_docstring_first.py b/pre_commit_hooks/check_docstring_first.py index 1744919c..d55f08a5 100644 --- a/pre_commit_hooks/check_docstring_first.py +++ b/pre_commit_hooks/check_docstring_first.py @@ -28,13 +28,13 @@ def check_docstring_first(src: bytes, filename: str = '') -> int: if tok_type == tokenize.STRING and scol == 0: if found_docstring_line is not None: print( - f'{filename}:{sline} Multiple module docstrings ' + f'{filename}:{sline}: Multiple module docstrings ' f'(first docstring on line {found_docstring_line}).', ) return 1 elif found_code_line is not None: print( - f'{filename}:{sline} Module docstring appears after code ' + f'{filename}:{sline}: Module docstring appears after code ' f'(code seen on line {found_code_line}).', ) return 1 diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py index 22031a29..15ec284a 100644 --- a/pre_commit_hooks/check_merge_conflict.py +++ b/pre_commit_hooks/check_merge_conflict.py @@ -10,6 +10,7 @@ CONFLICT_PATTERNS = [ b'<<<<<<< ', b'======= ', + b'=======\r\n', b'=======\n', b'>>>>>>> ', ] @@ -39,12 +40,12 @@ def main(argv: Sequence[str] | None = None) -> int: retcode = 0 for filename in args.filenames: with open(filename, 'rb') as inputfile: - for i, line in enumerate(inputfile): + for i, line in enumerate(inputfile, start=1): for pattern in CONFLICT_PATTERNS: if line.startswith(pattern): print( - f'Merge conflict string "{pattern.decode()}" ' - f'found in {filename}:{i + 1}', + f'{filename}:{i}: Merge conflict string ' + f'{pattern.strip().decode()!r} found', ) retcode = 1 diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 00b67983..9ada657a 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -65,7 +65,7 @@ def check_file(filename: str) -> int: visitor.visit(ast_obj) for bp in visitor.breakpoints: - print(f'{filename}:{bp.line}:{bp.col} - {bp.name} {bp.reason}') + print(f'{filename}:{bp.line}:{bp.col}: {bp.name} {bp.reason}') return int(bool(visitor.breakpoints)) diff --git a/tests/check_docstring_first_test.py b/tests/check_docstring_first_test.py index 079896f1..8bafae82 100644 --- a/tests/check_docstring_first_test.py +++ b/tests/check_docstring_first_test.py @@ -17,7 +17,7 @@ b'from __future__ import unicode_literals\n' b'"foo"\n', 1, - '{filename}:2 Module docstring appears after code ' + '{filename}:2: Module docstring appears after code ' '(code seen on line 1).\n', ), # Test double docstring @@ -26,7 +26,7 @@ b'from __future__ import absolute_import\n' b'"fake docstring"\n', 1, - '{filename}:3 Multiple module docstrings ' + '{filename}:3: Multiple module docstrings ' '(first docstring on line 1).\n', ), # Test multiple lines of code above @@ -35,7 +35,7 @@ b'import sys\n' b'"docstring"\n', 1, - '{filename}:3 Module docstring appears after code ' + '{filename}:3: Module docstring appears after code ' '(code seen on line 1).\n', ), # String literals in expressions are ok. diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py index d3322db1..76c4283c 100644 --- a/tests/check_merge_conflict_test.py +++ b/tests/check_merge_conflict_test.py @@ -101,8 +101,14 @@ def repository_pending_merge(tmpdir): @pytest.mark.usefixtures('f1_is_a_conflict_file') -def test_merge_conflicts_git(): +def test_merge_conflicts_git(capsys): assert main(['f1']) == 1 + out, _ = capsys.readouterr() + assert out == ( + "f1:1: Merge conflict string '<<<<<<<' found\n" + "f1:3: Merge conflict string '=======' found\n" + "f1:5: Merge conflict string '>>>>>>>' found\n" + ) @pytest.mark.parametrize( @@ -139,7 +145,7 @@ def test_care_when_assumed_merge(tmpdir): assert main([str(f.realpath()), '--assume-in-merge']) == 1 -def test_worktree_merge_conflicts(f1_is_a_conflict_file, tmpdir): +def test_worktree_merge_conflicts(f1_is_a_conflict_file, tmpdir, capsys): worktree = tmpdir.join('worktree') cmd_output('git', 'worktree', 'add', str(worktree)) with worktree.as_cwd(): @@ -148,4 +154,4 @@ def test_worktree_merge_conflicts(f1_is_a_conflict_file, tmpdir): ) msg = f1_is_a_conflict_file.join('.git/worktrees/worktree/MERGE_MSG') assert msg.exists() - test_merge_conflicts_git() + test_merge_conflicts_git(capsys) diff --git a/tests/debug_statement_hook_test.py b/tests/debug_statement_hook_test.py index 349fe89c..5a8e0bb2 100644 --- a/tests/debug_statement_hook_test.py +++ b/tests/debug_statement_hook_test.py @@ -55,7 +55,9 @@ def test_non_utf8_file(tmpdir): assert main((str(f_py),)) == 0 -def test_py37_breakpoint(tmpdir): +def test_py37_breakpoint(tmpdir, capsys): f_py = tmpdir.join('f.py') f_py.write('def f():\n breakpoint()\n') assert main((str(f_py),)) == 1 + out, _ = capsys.readouterr() + assert out == f'{f_py}:2:4: breakpoint called\n' From db7346d375eda68a0174f2c057dd97f2fbffe030 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 6 Apr 2022 17:12:57 -0400 Subject: [PATCH 227/334] v4.2.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 23 +++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c7edbe96..8804d9d2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e72022..6a2ae68b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +4.2.0 - 2022-04-06 +================== + +### Features +- `name-tests-test`: updated display text. + - #713 PR by @asottile. +- `check-docstring-first`: make output more parsable. + - #748 PR by @asottile. +- `check-merge-conflict`: make output more parsable. + - #748 PR by @asottile. +- `debug-statements`: make output more parsable. + - #748 PR by @asottile. + +### Fixes +- `check-merge-conflict`: fix detection of `======` conflict marker on windows. + - #748 PR by @asottile. + +### Updating +- Drop python<3.7. + - #719 PR by @asottile. +- Changed default branch from `master` to `main`. + - #744 PR by @asottile. + 4.1.0 - 2021-12-22 ================== diff --git a/README.md b/README.md index 63212d14..73688319 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 # Use the ref you want to point at + rev: v4.2.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 5b0f7ca5..8247f311 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.1.0 +version = 4.2.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 5d69701a83888680cf3022c842c8c1ebeb53d7f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 20:55:02 +0000 Subject: [PATCH 228/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.31.1 → v2.32.0](https://github.com/asottile/pyupgrade/compare/v2.31.1...v2.32.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8804d9d2..823ef3ee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.31.1 + rev: v2.32.0 hooks: - id: pyupgrade args: [--py37-plus] From 3a4b21ad3fb13c92491fd10260323c3a8d0ea5be Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Apr 2022 19:50:45 +0000 Subject: [PATCH 229/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/add-trailing-comma: v2.2.2 → v2.2.3](https://github.com/asottile/add-trailing-comma/compare/v2.2.2...v2.2.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 823ef3ee..fcff0fcc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.2.2 + rev: v2.2.3 hooks: - id: add-trailing-comma args: [--py36-plus] From aa56da853574fa6128b06cf53f5b6bdbc16d4534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Mon, 25 Apr 2022 12:20:30 +0200 Subject: [PATCH 230/334] Document check-merge-conflict argument Document --assume-in-merge in README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 73688319..2c8cf4f4 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Attempts to load all json files to verify syntax. #### `check-merge-conflict` Check for files that contain merge conflict strings. + - `--assume-in-merge` - Allows running the hook when there is no ongoing merge operation #### `check-shebang-scripts-are-executable` Checks that scripts with shebangs are executable. From 2cbabf90cc2b7544706f741610908b6a2920199c Mon Sep 17 00:00:00 2001 From: Kurt von Laven Date: Fri, 18 Feb 2022 23:51:58 -0800 Subject: [PATCH 231/334] Check Git core.fileMode rather than infer from OS. There was already a guard preventing the check-executables-have-shebangs hook from raising false positives on win32 by looking up the Git file mode rather than relying on the file mode in the file system. Git already automatically probes the file system for executable bit support. Leverage Git's core.fileMode config variable to prevent false positives on all file systems that don't track executable bits. --- pre_commit_hooks/check_executables_have_shebangs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index 6b5402ac..d8e4f490 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -15,7 +15,10 @@ def check_executables(paths: list[str]) -> int: - if sys.platform == 'win32': # pragma: win32 cover + fs_tracks_executable_bit = cmd_output( + 'git', 'config', 'core.fileMode', retcode=None, + ).strip() + if fs_tracks_executable_bit == 'false': # pragma: win32 cover return _check_git_filemode(paths) else: # pragma: win32 no cover retv = 0 From 54611ef08ac1db0935a3772750ed1dad38c5d41b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 20:18:30 +0000 Subject: [PATCH 232/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v3.0.1 → v3.1.0](https://github.com/asottile/reorder_python_imports/compare/v3.0.1...v3.1.0) - [github.com/pre-commit/mirrors-mypy: v0.942 → v0.950](https://github.com/pre-commit/mirrors-mypy/compare/v0.942...v0.950) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fcff0fcc..959ff15d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.0.1 + rev: v3.1.0 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.942 + rev: v0.950 hooks: - id: mypy additional_dependencies: [types-all] From 821fb690da5445e4f5d1de3cbe7d6028fbd54761 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 20:28:29 +0000 Subject: [PATCH 233/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.32.0 → v2.32.1](https://github.com/asottile/pyupgrade/compare/v2.32.0...v2.32.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 959ff15d..5322694d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.32.0 + rev: v2.32.1 hooks: - id: pyupgrade args: [--py37-plus] From bd70bc119d0c8ec42ae8ea21baf481fda2fc4c53 Mon Sep 17 00:00:00 2001 From: MDW Date: Thu, 26 May 2022 17:31:24 +0200 Subject: [PATCH 234/334] Add instruction to change executable mode on windows --- pre_commit_hooks/check_shebang_scripts_are_executable.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pre_commit_hooks/check_shebang_scripts_are_executable.py b/pre_commit_hooks/check_shebang_scripts_are_executable.py index 0f35650b..621696ce 100644 --- a/pre_commit_hooks/check_shebang_scripts_are_executable.py +++ b/pre_commit_hooks/check_shebang_scripts_are_executable.py @@ -34,6 +34,8 @@ def _message(path: str) -> None: f'{path}: has a shebang but is not marked executable!\n' f' If it is supposed to be executable, try: ' f'`chmod +x {shlex.quote(path)}`\n' + f' If on Windows, you may also need to: ' + f'`git add --chmod=+x {shlex.quote(path)}`\n' f' If it not supposed to be executable, double-check its shebang ' f'is wanted.\n', file=sys.stderr, From 091d224a6cf0ea52627ab7732a807c7f7ab519ab Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 May 2022 20:33:16 +0000 Subject: [PATCH 235/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.950 → v0.960](https://github.com/pre-commit/mirrors-mypy/compare/v0.950...v0.960) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5322694d..39838a10 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.950 + rev: v0.960 hooks: - id: mypy additional_dependencies: [types-all] From fc88f3fa495385e6b367f7c4c8cf10940ad053da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Tue, 24 May 2022 08:44:13 +0200 Subject: [PATCH 236/334] Use tomli and tomllib instead of toml --- pre_commit_hooks/check_toml.py | 11 ++++++++--- setup.cfg | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pre_commit_hooks/check_toml.py b/pre_commit_hooks/check_toml.py index 88f70865..0407371e 100644 --- a/pre_commit_hooks/check_toml.py +++ b/pre_commit_hooks/check_toml.py @@ -1,9 +1,13 @@ from __future__ import annotations import argparse +import sys from typing import Sequence -import toml +if sys.version_info >= (3, 11): # pragma: >=3.11 cover + import tomllib +else: # pragma: <3.11 cover + import tomli as tomllib def main(argv: Sequence[str] | None = None) -> int: @@ -14,8 +18,9 @@ def main(argv: Sequence[str] | None = None) -> int: retval = 0 for filename in args.filenames: try: - toml.load(filename) - except toml.TomlDecodeError as exc: + with open(filename, mode='rb') as fp: + tomllib.load(fp) + except tomllib.TOMLDecodeError as exc: print(f'{filename}: {exc}') retval = 1 return retval diff --git a/setup.cfg b/setup.cfg index 8247f311..0f249c13 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,7 +24,7 @@ classifiers = packages = find: install_requires = ruamel.yaml>=0.15 - toml + tomli>=1.1.0;python_version<"3.11" python_requires = >=3.7 [options.packages.find] From d17fe994c600d738899849138a70588d3606a429 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 6 Jun 2022 12:24:03 -0400 Subject: [PATCH 237/334] set stages for `check-added-large-files` looks like this was accidentally running on `commit-msg` hooks --- .pre-commit-hooks.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 9e835d58..c28c1c81 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -3,6 +3,7 @@ description: prevents giant files from being committed. entry: check-added-large-files language: python + stages: [commit, push, manual] - id: check-ast name: check python ast description: simply checks whether the files parse as valid python. From 412564fa952d5d2bed3b2fd239da591e4bc4b513 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 7 Jun 2022 09:10:42 -0700 Subject: [PATCH 238/334] add --pytest-test-first convention --- .pre-commit-hooks.yaml | 2 +- README.md | 6 ++-- pre_commit_hooks/tests_should_end_in_test.py | 31 ++++++++++++++++---- tests/tests_should_end_in_test_test.py | 5 ++++ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index c28c1c81..1a6056bd 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -164,7 +164,7 @@ types: [text] - id: name-tests-test name: python tests naming - description: this verifies that test files are named correctly. + description: verifies that test files are named correctly. entry: name-tests-test language: python files: (^|/)tests/.+\.py$ diff --git a/README.md b/README.md index 2c8cf4f4..28195777 100644 --- a/README.md +++ b/README.md @@ -142,8 +142,10 @@ Replaces or checks mixed line ending. - `no` - Checks if there is any mixed line ending without modifying any file. #### `name-tests-test` -Assert that files in tests/ end in `_test.py`. - - Use `args: ['--django']` to match `test*.py` instead. +verifies that test files are named correctly. +- `--pytest` (the default): ensure tests match `.*_test\.py` +- `--pytest-test-first`: ensure tests match `test_.*\.py` +- `--django` / `--unittest`: ensure tests match `test.*\.py` #### `no-commit-to-branch` Protect specific branches from direct checkins. diff --git a/pre_commit_hooks/tests_should_end_in_test.py b/pre_commit_hooks/tests_should_end_in_test.py index e1ffe367..e7842af7 100644 --- a/pre_commit_hooks/tests_should_end_in_test.py +++ b/pre_commit_hooks/tests_should_end_in_test.py @@ -9,23 +9,42 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*') - parser.add_argument( - '--django', default=False, action='store_true', - help='Use Django-style test naming pattern (test*.py)', + mutex = parser.add_mutually_exclusive_group() + mutex.add_argument( + '--pytest', + dest='pattern', + action='store_const', + const=r'.*_test\.py', + default=r'.*_test\.py', + help='(the default) ensure tests match %(const)s', + ) + mutex.add_argument( + '--pytest-test-first', + dest='pattern', + action='store_const', + const=r'test_.*\.py', + help='ensure tests match %(const)s', + ) + mutex.add_argument( + '--django', '--unittest', + dest='pattern', + action='store_const', + const=r'test.*\.py', + help='ensure tests match %(const)s', ) args = parser.parse_args(argv) retcode = 0 - test_name_pattern = r'test.*\.py' if args.django else r'.*_test\.py' + reg = re.compile(args.pattern) for filename in args.filenames: base = os.path.basename(filename) if ( - not re.match(test_name_pattern, base) and + not reg.fullmatch(base) and not base == '__init__.py' and not base == 'conftest.py' ): retcode = 1 - print(f'{filename} does not match pattern "{test_name_pattern}"') + print(f'{filename} does not match pattern "{args.pattern}"') return retcode diff --git a/tests/tests_should_end_in_test_test.py b/tests/tests_should_end_in_test_test.py index dc3744b8..2b5a0dea 100644 --- a/tests/tests_should_end_in_test_test.py +++ b/tests/tests_should_end_in_test_test.py @@ -43,3 +43,8 @@ def test_main_not_django_fails(): def test_main_django_fails(): ret = main(['--django', 'foo_test.py', 'test_bar.py', 'test_baz.py']) assert ret == 1 + + +def test_main_pytest_test_first(): + assert main(['--pytest-test-first', 'test_foo.py']) == 0 + assert main(['--pytest-test-first', 'foo_test.py']) == 1 From 3298ddab3c13dd77d6ce1fc0baf97691430d84b0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 7 Jun 2022 10:08:29 -0700 Subject: [PATCH 239/334] v4.3.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 21 +++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 39838a10..0440edfb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.3.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a2ae68b..d6e3171d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +4.3.0 - 2022-06-07 +================== + +### Features +- `check-executables-have-shebangs`: use `git config core.fileMode` to + determine if it should query `git`. + - #730 PR by @Kurt-von-Laven. +- `name-tests-test`: add `--pytest-test-first` test convention. + - #779 PR by @asottile. + +### Fixes +- `check-shebang-scripts-are-executable`: update windows instructions. + - #774 PR by @mdeweerd. + - #770 issue by @mdeweerd. +- `check-toml`: use stdlib `tomllib` when available. + - #771 PR by @DanielNoord. + - #755 issue by @sognetic. +- `check-added-large-files`: don't run on non-file `stages`. + - #778 PR by @asottile. + - #777 issue by @skyj. + 4.2.0 - 2022-04-06 ================== diff --git a/README.md b/README.md index 28195777..411529a0 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 # Use the ref you want to point at + rev: v4.3.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 0f249c13..f5015715 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.2.0 +version = 4.3.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 2345f2efb2528f27d407a987f830de206c5ad9fa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:56:48 +0000 Subject: [PATCH 240/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.32.1 → v2.34.0](https://github.com/asottile/pyupgrade/compare/v2.32.1...v2.34.0) - [github.com/pre-commit/mirrors-mypy: v0.960 → v0.961](https://github.com/pre-commit/mirrors-mypy/compare/v0.960...v0.961) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0440edfb..c5299f80 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.32.1 + rev: v2.34.0 hooks: - id: pyupgrade args: [--py37-plus] @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.960 + rev: v0.961 hooks: - id: mypy additional_dependencies: [types-all] From dd347f86bc32236d7f9a5a82e718908c557a8708 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 21:58:20 +0000 Subject: [PATCH 241/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v3.1.0 → v3.3.0](https://github.com/asottile/reorder_python_imports/compare/v3.1.0...v3.3.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c5299f80..1e1b4a4d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.1.0 + rev: v3.3.0 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] From c2b640f9cbec13d7608fb529f86322bde190fb7a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Jul 2022 21:25:32 +0000 Subject: [PATCH 242/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v3.3.0 → v3.8.1](https://github.com/asottile/reorder_python_imports/compare/v3.3.0...v3.8.1) - [github.com/asottile/pyupgrade: v2.34.0 → v2.37.1](https://github.com/asottile/pyupgrade/compare/v2.34.0...v2.37.1) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1e1b4a4d..d416bc65 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.3.0 + rev: v3.8.1 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.34.0 + rev: v2.37.1 hooks: - id: pyupgrade args: [--py37-plus] From 085ce874eaf0d309d9c36c4254fedf18236afbea Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 21:44:53 +0000 Subject: [PATCH 243/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v1.20.1 → v1.20.2](https://github.com/asottile/setup-cfg-fmt/compare/v1.20.1...v1.20.2) - [github.com/asottile/reorder_python_imports: v3.8.1 → v3.8.2](https://github.com/asottile/reorder_python_imports/compare/v3.8.1...v3.8.2) - [github.com/asottile/pyupgrade: v2.37.1 → v2.37.2](https://github.com/asottile/pyupgrade/compare/v2.37.1...v2.37.2) - [github.com/pre-commit/mirrors-mypy: v0.961 → v0.971](https://github.com/pre-commit/mirrors-mypy/compare/v0.961...v0.971) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d416bc65..ad8228be 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,11 +10,11 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.20.1 + rev: v1.20.2 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.8.1 + rev: v3.8.2 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.37.1 + rev: v2.37.2 hooks: - id: pyupgrade args: [--py37-plus] @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.961 + rev: v0.971 hooks: - id: mypy additional_dependencies: [types-all] From ef24d53d5b0f814fa15a8f3ae170752a05d78258 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 22:41:09 +0000 Subject: [PATCH 244/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v1.20.2 → v2.0.0](https://github.com/asottile/setup-cfg-fmt/compare/v1.20.2...v2.0.0) - [github.com/asottile/pyupgrade: v2.37.2 → v2.37.3](https://github.com/asottile/pyupgrade/compare/v2.37.2...v2.37.3) - [github.com/PyCQA/flake8: 4.0.1 → 5.0.2](https://github.com/PyCQA/flake8/compare/4.0.1...5.0.2) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad8228be..cf80e8c8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.20.2 + rev: v2.0.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.37.2 + rev: v2.37.3 hooks: - id: pyupgrade args: [--py37-plus] @@ -33,7 +33,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 5.0.2 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy From 52dac67bb432cf71239ac4f527af2ec37bbdf3f4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 22:41:52 +0000 Subject: [PATCH 245/334] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- setup.cfg | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup.cfg b/setup.cfg index f5015715..d4658e22 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,10 +13,6 @@ classifiers = License :: OSI Approved :: MIT License Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy From ceeb44086c97808cb549aed3a79f8fb716b71255 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 22:25:11 +0000 Subject: [PATCH 246/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 5.0.2 → 5.0.4](https://github.com/PyCQA/flake8/compare/5.0.2...5.0.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf80e8c8..b6f31918 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 5.0.2 + rev: 5.0.4 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy From f508ebb46ebfce5dbfacf888a0d8aba694beb872 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Aug 2022 21:15:55 +0000 Subject: [PATCH 247/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-autopep8: v1.6.0 → v1.7.0](https://github.com/pre-commit/mirrors-autopep8/compare/v1.6.0...v1.7.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b6f31918..9478a1fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.6.0 + rev: v1.7.0 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From 1f52105403cb91b1670f560ddf69539671eb5516 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 22:48:44 +0000 Subject: [PATCH 248/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.37.3 → v2.38.0](https://github.com/asottile/pyupgrade/compare/v2.37.3...v2.38.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9478a1fe..194cee79 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.37.3 + rev: v2.38.0 hooks: - id: pyupgrade args: [--py37-plus] From 3c82985dccfdd049cf726776bbed081b09f335c0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 22:58:10 +0000 Subject: [PATCH 249/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v3.8.2 → v3.8.3](https://github.com/asottile/reorder_python_imports/compare/v3.8.2...v3.8.3) - [github.com/asottile/add-trailing-comma: v2.2.3 → v2.3.0](https://github.com/asottile/add-trailing-comma/compare/v2.2.3...v2.3.0) - [github.com/asottile/pyupgrade: v2.38.0 → v2.38.2](https://github.com/asottile/pyupgrade/compare/v2.38.0...v2.38.2) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 194cee79..5e7f2330 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,17 +14,17 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.8.2 + rev: v3.8.3 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.2.3 + rev: v2.3.0 hooks: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.38.0 + rev: v2.38.2 hooks: - id: pyupgrade args: [--py37-plus] From 3a406f068f951c247adb6ebfadf431aeb066526b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 22:51:47 +0000 Subject: [PATCH 250/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.971 → v0.981](https://github.com/pre-commit/mirrors-mypy/compare/v0.971...v0.981) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5e7f2330..68bcddcb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.971 + rev: v0.981 hooks: - id: mypy additional_dependencies: [types-all] From a9b6a7e7fa51df6e93780b2e7dd15a0d5b943ba0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Tue, 4 Oct 2022 15:56:38 -0400 Subject: [PATCH 251/334] add forbid-submodules hook --- .pre-commit-hooks.yaml | 6 ++++++ README.md | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 1a6056bd..f8523d4a 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -156,6 +156,12 @@ language: python entry: forbid-new-submodules types: [directory] +- id: forbid-submodules + name: forbid submodules + description: forbids any submodules in the repository + language: fail + entry: 'submodules are not allowed in this repository:' + types: [directory] - id: mixed-line-ending name: mixed line ending description: replaces or checks mixed line ending. diff --git a/README.md b/README.md index 411529a0..1026d3fd 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,12 @@ The following arguments are available: #### `forbid-new-submodules` Prevent addition of new git submodules. +This is intended as a helper to migrate away from submodules. If you want to +ban them entirely use `forbid-submodules` + +#### `forbid-submodules` +forbids any submodules in the repository. + #### `mixed-line-ending` Replaces or checks mixed line ending. - `--fix={auto,crlf,lf,no}` From 8fe064d0bd7ed0fbb665774f1aa77845ed56c99b Mon Sep 17 00:00:00 2001 From: Nuz / Lovegood Date: Sat, 8 Oct 2022 10:58:42 -0700 Subject: [PATCH 252/334] Alphabetize & clarify `file-contents-sorter` in README --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1026d3fd..27dae973 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,17 @@ This hook replaces double quoted strings with single quoted strings. #### `end-of-file-fixer` Makes sure files end in a newline and only a newline. +#### `file-contents-sorter` +Sort the lines in specified files (defaults to alphabetical). +You must provide the target [`files`](https://pre-commit.com/#config-files) as input, for example: + +```yaml + - id: file-contents-sorter + files: \.gitignore +``` + +Note that this hook WILL remove blank lines and does NOT respect any comments. + #### `fix-byte-order-marker` removes UTF-8 byte order marker @@ -121,11 +132,6 @@ removes UTF-8 byte order marker Add `# -*- coding: utf-8 -*-` to the top of python files. - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) -#### `file-contents-sorter` -Sort the lines in specified files (defaults to alphabetical). -You must provide list of target files as input to it. -Note that this hook WILL remove blank lines and does NOT respect any comments. - The following arguments are available: - `--ignore-case` - fold lower case to upper case characters. - `--unique` - ensure each line is unique. From 14ac91fb70066f16a3093580c2f28de65837e138 Mon Sep 17 00:00:00 2001 From: Nuz / Lovegood Date: Sat, 8 Oct 2022 11:16:50 -0700 Subject: [PATCH 253/334] Remove example. --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 27dae973..6dcbf0d1 100644 --- a/README.md +++ b/README.md @@ -116,13 +116,7 @@ Makes sure files end in a newline and only a newline. #### `file-contents-sorter` Sort the lines in specified files (defaults to alphabetical). -You must provide the target [`files`](https://pre-commit.com/#config-files) as input, for example: - -```yaml - - id: file-contents-sorter - files: \.gitignore -``` - +You must provide the target [`files`](https://pre-commit.com/#config-files) as input. Note that this hook WILL remove blank lines and does NOT respect any comments. #### `fix-byte-order-marker` From f9af4e26688c83f09906c39e99469cd0c46861db Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 23:49:59 +0000 Subject: [PATCH 254/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder_python_imports: v3.8.3 → v3.8.4](https://github.com/asottile/reorder_python_imports/compare/v3.8.3...v3.8.4) - [github.com/asottile/pyupgrade: v2.38.2 → v3.1.0](https://github.com/asottile/pyupgrade/compare/v2.38.2...v3.1.0) - [github.com/pre-commit/mirrors-mypy: v0.981 → v0.982](https://github.com/pre-commit/mirrors-mypy/compare/v0.981...v0.982) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 68bcddcb..2317f74c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.8.3 + rev: v3.8.4 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.38.2 + rev: v3.1.0 hooks: - id: pyupgrade args: [--py37-plus] @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.981 + rev: v0.982 hooks: - id: mypy additional_dependencies: [types-all] From 596f4aece86c48efd693cdc0ab624fc3849acdad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 23:10:37 +0000 Subject: [PATCH 255/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v2.0.0 → v2.1.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.0.0...v2.1.0) - [github.com/asottile/reorder_python_imports: v3.8.4 → v3.8.5](https://github.com/asottile/reorder_python_imports/compare/v3.8.4...v3.8.5) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2317f74c..dad93af9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,11 +10,11 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.0.0 + rev: v2.1.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.8.4 + rev: v3.8.5 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] From 0a7d3b7d597e371384da84388947e3bf0fb367ba Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 23:27:38 +0000 Subject: [PATCH 256/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v2.1.0 → v2.2.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.1.0...v2.2.0) - [github.com/asottile/reorder_python_imports: v3.8.5 → v3.9.0](https://github.com/asottile/reorder_python_imports/compare/v3.8.5...v3.9.0) - [github.com/asottile/pyupgrade: v3.1.0 → v3.2.0](https://github.com/asottile/pyupgrade/compare/v3.1.0...v3.2.0) - [github.com/pre-commit/mirrors-autopep8: v1.7.0 → v2.0.0](https://github.com/pre-commit/mirrors-autopep8/compare/v1.7.0...v2.0.0) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dad93af9..ac84dad2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,11 +10,11 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.1.0 + rev: v2.2.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder_python_imports - rev: v3.8.5 + rev: v3.9.0 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] @@ -24,12 +24,12 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.1.0 + rev: v3.2.0 hooks: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.7.0 + rev: v2.0.0 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From c44770d97229dac922f7abf8c35ca1b19e5a36f2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 23:36:53 +0000 Subject: [PATCH 257/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.2.0 → v3.2.2](https://github.com/asottile/pyupgrade/compare/v3.2.0...v3.2.2) - [github.com/pre-commit/mirrors-mypy: v0.982 → v0.990](https://github.com/pre-commit/mirrors-mypy/compare/v0.982...v0.990) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ac84dad2..afd1fa8d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.2.0 + rev: v3.2.2 hooks: - id: pyupgrade args: [--py37-plus] @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.982 + rev: v0.990 hooks: - id: mypy additional_dependencies: [types-all] From 360df52788d2b6bdc26e62cbfa00aa3d85cf6599 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 16 Nov 2022 19:19:56 -0500 Subject: [PATCH 258/334] remove no_implicit_optional this is the default in mypy 0.990 Committed via https://github.com/asottile/all-repos --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index d4658e22..30688d95 100644 --- a/setup.cfg +++ b/setup.cfg @@ -75,7 +75,6 @@ check_untyped_defs = true disallow_any_generics = true disallow_incomplete_defs = true disallow_untyped_defs = true -no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true From a63d8f319e81007300e79e782488a3a4886e6107 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Nov 2022 23:12:14 +0000 Subject: [PATCH 259/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.990 → v0.991](https://github.com/pre-commit/mirrors-mypy/compare/v0.990...v0.991) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index afd1fa8d..86704654 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.990 + rev: v0.991 hooks: - id: mypy additional_dependencies: [types-all] From f71fa2c1f9cf5cb705f73dffe4b21f7c61470ba9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 23 Nov 2022 14:35:47 -0500 Subject: [PATCH 260/334] v4.4.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86704654..cfe2378f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index d6e3171d..36d5aebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +4.4.0 - 2022-11-23 +================== + +### Features +- `forbid-submodules`: new hook which outright bans submodules. + - #815 PR by @asottile. + - #707 issue by @ChiefGokhlayeh. + 4.3.0 - 2022-06-07 ================== diff --git a/README.md b/README.md index 6dcbf0d1..9aa966dd 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 # Use the ref you want to point at + rev: v4.4.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 30688d95..834b3e82 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.3.0 +version = 4.4.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 6c514cc2c03af765f9455f31ab0781b5d49e916d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 01:10:15 +0000 Subject: [PATCH 261/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 5.0.4 → 6.0.0](https://github.com/PyCQA/flake8/compare/5.0.4...6.0.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cfe2378f..c4c46b41 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 5.0.4 + rev: 6.0.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy From 9c40982c4a57971255e4adb4e5ec2705ff3e6e27 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:51:59 +0000 Subject: [PATCH 262/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.2.2 → v3.3.0](https://github.com/asottile/pyupgrade/compare/v3.2.2...v3.3.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4c46b41..a1925a37 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.2.2 + rev: v3.3.0 hooks: - id: pyupgrade args: [--py37-plus] From a18227963d41a05f183ed52828f0cb2d89a4ba8a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 00:40:00 +0000 Subject: [PATCH 263/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/add-trailing-comma: v2.3.0 → v2.4.0](https://github.com/asottile/add-trailing-comma/compare/v2.3.0...v2.4.0) - [github.com/asottile/pyupgrade: v3.3.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v3.3.0...v3.3.1) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a1925a37..4caa5cbc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,12 +19,12 @@ repos: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.3.0 + rev: v2.4.0 hooks: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.3.0 + rev: v3.3.1 hooks: - id: pyupgrade args: [--py37-plus] From 23e603312ab090a9bb449e5639167bda6362b1e1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 00:30:13 +0000 Subject: [PATCH 264/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-autopep8: v2.0.0 → v2.0.1](https://github.com/pre-commit/mirrors-autopep8/compare/v2.0.0...v2.0.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4caa5cbc..74db87aa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v2.0.0 + rev: v2.0.1 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From a13cf6492ed11a199d4dcf19d30f807394bd4d8b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 29 Dec 2022 18:11:25 -0500 Subject: [PATCH 265/334] azure pipelines -> github actions --- .github/workflows/main.yml | 19 +++++++++++++++++++ README.md | 3 +-- azure-pipelines.yml | 23 ----------------------- 3 files changed, 20 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/main.yml delete mode 100644 azure-pipelines.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..5ffdb814 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,19 @@ +name: main + +on: + push: + branches: [main, test-me-*] + tags: + pull_request: + +jobs: + main-windows: + uses: asottile/workflows/.github/workflows/tox.yml@v1.0.0 + with: + env: '["py38"]' + os: windows-latest + main-linux: + uses: asottile/workflows/.github/workflows/tox.yml@v1.0.0 + with: + env: '["py37", "py38", "py39", "py310"]' + os: ubuntu-latest diff --git a/README.md b/README.md index 9aa966dd..3b3b3301 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -[![Build Status](https://asottile.visualstudio.com/asottile/_apis/build/status/pre-commit.pre-commit-hooks?branchName=main)](https://asottile.visualstudio.com/asottile/_build/latest?definitionId=17&branchName=main) -[![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/asottile/asottile/17/main.svg)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=17&branchName=main) +[![build status](https://github.com/pre-commit/pre-commit-hooks/actions/workflows/main.yml/badge.svg)](https://github.com/pre-commit/pre-commit-hooks/actions/workflows/main.yml) [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pre-commit/pre-commit-hooks/main.svg)](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit-hooks/main) pre-commit-hooks diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 117b014f..00000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,23 +0,0 @@ -trigger: - branches: - include: [main, test-me-*] - tags: - include: ['*'] - -resources: - repositories: - - repository: asottile - type: github - endpoint: github - name: asottile/azure-pipeline-templates - ref: refs/tags/v2.4.0 - -jobs: -- template: job--python-tox.yml@asottile - parameters: - toxenvs: [py38] - os: windows -- template: job--python-tox.yml@asottile - parameters: - toxenvs: [py37, py38, py39, py310] - os: linux From 03cb9e7007cdd1fcbeda59fc1f9bd7950b03aadc Mon Sep 17 00:00:00 2001 From: Lev Blit Date: Sat, 14 Jan 2023 13:27:25 +0200 Subject: [PATCH 266/334] add constraints file to requirements-txt-fixer files --- .pre-commit-hooks.yaml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index f8523d4a..c0d811ca 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -185,7 +185,7 @@ description: sorts entries in requirements.txt. entry: requirements-txt-fixer language: python - files: requirements.*\.txt$ + files: (requirements|constraints).*\.txt$ - id: sort-simple-yaml name: sort simple yaml files description: sorts simple yaml files which consist only of top-level keys, preserving comments and blocks. diff --git a/README.md b/README.md index 3b3b3301..9751c00b 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ the following commandline options: - `--top-keys comma,separated,keys` - Keys to keep at the top of mappings. #### `requirements-txt-fixer` -Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0` +Sorts entries in requirements.txt and constraints.txt and removes incorrect entry for `pkg-resources==0.0.0` #### `sort-simple-yaml` Sorts simple YAML files which consist only of top-level From 6c509f9650ac0d5410031cb1ab542c2e78299f55 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 02:25:07 +0000 Subject: [PATCH 267/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v0.991 → v1.0.0](https://github.com/pre-commit/mirrors-mypy/compare/v0.991...v1.0.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 74db87aa..6ee350c4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.991 + rev: v1.0.0 hooks: - id: mypy additional_dependencies: [types-all] From be44903ab6ed5acbaaa2ccabfe3b3d8b16bf0365 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 02:06:38 +0000 Subject: [PATCH 268/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.0.0 → v1.0.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.0.0...v1.0.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ee350c4..93d40f57 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.0 + rev: v1.0.1 hooks: - id: mypy additional_dependencies: [types-all] From e556d94c70c061f76c59d5412df912fc1b29c01f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Mar 2023 02:51:56 +0000 Subject: [PATCH 269/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-autopep8: v2.0.1 → v2.0.2](https://github.com/pre-commit/mirrors-autopep8/compare/v2.0.1...v2.0.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 93d40f57..a2c78182 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v2.0.1 + rev: v2.0.2 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From 49cf0d461aa0f910fc0d4985925ee02a26d4d77d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 03:18:43 +0000 Subject: [PATCH 270/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.0.1 → v1.1.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.0.1...v1.1.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a2c78182..0d1f9830 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.1 + rev: v1.1.1 hooks: - id: mypy additional_dependencies: [types-all] From 56107f53015d4d5b9c4dfc769b11d23321a3f933 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 02:57:50 +0000 Subject: [PATCH 271/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.1.1 → v1.2.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.1.1...v1.2.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0d1f9830..94bbb0fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.1.1 + rev: v1.2.0 hooks: - id: mypy additional_dependencies: [types-all] From f34b527ff1164f11a0ff418ba1004a11fb52badc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 03:21:09 +0000 Subject: [PATCH 272/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.3.1 → v3.3.2](https://github.com/asottile/pyupgrade/compare/v3.3.1...v3.3.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 94bbb0fd..f3fc890d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.3.2 hooks: - id: pyupgrade args: [--py37-plus] From 894c7c474f437e255f1ce28da1910fb7dd93b782 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 04:04:00 +0000 Subject: [PATCH 273/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - https://github.com/asottile/reorder_python_imports → https://github.com/asottile/reorder-python-imports - [github.com/asottile/pyupgrade: v3.3.2 → v3.4.0](https://github.com/asottile/pyupgrade/compare/v3.3.2...v3.4.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f3fc890d..89bf5724 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: rev: v2.2.0 hooks: - id: setup-cfg-fmt -- repo: https://github.com/asottile/reorder_python_imports +- repo: https://github.com/asottile/reorder-python-imports rev: v3.9.0 hooks: - id: reorder-python-imports @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.3.2 + rev: v3.4.0 hooks: - id: pyupgrade args: [--py37-plus] From 35d6db054ad8bf9a4c098256d8bb8ee02a93b449 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 03:20:22 +0000 Subject: [PATCH 274/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.2.0 → v1.3.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.2.0...v1.3.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 89bf5724..80d2bc87 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.2.0 + rev: v1.3.0 hooks: - id: mypy additional_dependencies: [types-all] From f45f36e8ff99048e8b52d465d7d991c529a1d7fb Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 1 Jun 2023 19:12:53 -0400 Subject: [PATCH 275/334] fix tags trigger for github actions the old syntax worked for azure pipelines but not GHA Committed via https://github.com/asottile/all-repos --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5ffdb814..5f15eb2b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,7 +3,7 @@ name: main on: push: branches: [main, test-me-*] - tags: + tags: '*' pull_request: jobs: From 361ce37796e09f2b101b4467ef73af4a11f726da Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 03:14:19 +0000 Subject: [PATCH 276/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v2.2.0 → v2.3.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.2.0...v2.3.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 80d2bc87..aa9465b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.2.0 + rev: v2.3.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports From d05d4d7f17d5d569e6a49d082ac2db51fbbd5283 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 03:14:39 +0000 Subject: [PATCH 277/334] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 834b3e82..1603c7dc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,7 +8,7 @@ url = https://github.com/pre-commit/pre-commit-hooks author = Anthony Sottile author_email = asottile@umich.edu license = MIT -license_file = LICENSE +license_files = LICENSE classifiers = License :: OSI Approved :: MIT License Programming Language :: Python :: 3 From 7ed9210de75db9aa48dff03e93cd31448fb6ea25 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 03:58:38 +0000 Subject: [PATCH 278/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/add-trailing-comma: v2.4.0 → v2.5.1](https://github.com/asottile/add-trailing-comma/compare/v2.4.0...v2.5.1) - [github.com/asottile/pyupgrade: v3.4.0 → v3.6.0](https://github.com/asottile/pyupgrade/compare/v3.4.0...v3.6.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa9465b7..71d2845d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,12 +19,12 @@ repos: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.4.0 + rev: v2.5.1 hooks: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.4.0 + rev: v3.6.0 hooks: - id: pyupgrade args: [--py37-plus] From 36e6a062d2ed9af31a626eb2151a22b9f90598fa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 04:34:08 +0000 Subject: [PATCH 279/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder-python-imports: v3.9.0 → v3.10.0](https://github.com/asottile/reorder-python-imports/compare/v3.9.0...v3.10.0) - [github.com/asottile/pyupgrade: v3.6.0 → v3.7.0](https://github.com/asottile/pyupgrade/compare/v3.6.0...v3.7.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 71d2845d..adb980e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports - rev: v3.9.0 + rev: v3.10.0 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] @@ -24,7 +24,7 @@ repos: - id: add-trailing-comma args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.6.0 + rev: v3.7.0 hooks: - id: pyupgrade args: [--py37-plus] From 59a21098848eb0493a8011f2fdbd8b0e452dc27b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 03:52:03 +0000 Subject: [PATCH 280/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.3.0 → v1.4.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.3.0...v1.4.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index adb980e3..8938e897 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.3.0 + rev: v1.4.1 hooks: - id: mypy additional_dependencies: [types-all] From 50a9fefe01ebf7080b801488e9fcc36d6f9c7f24 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 1 Jul 2023 15:41:17 -0400 Subject: [PATCH 281/334] py38-plus Committed via https://github.com/asottile/all-repos --- .github/workflows/main.yml | 6 +++--- .pre-commit-config.yaml | 11 +++++------ setup.cfg | 2 +- tox.ini | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f15eb2b..088a066e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,12 +8,12 @@ on: jobs: main-windows: - uses: asottile/workflows/.github/workflows/tox.yml@v1.0.0 + uses: asottile/workflows/.github/workflows/tox.yml@v1.5.0 with: env: '["py38"]' os: windows-latest main-linux: - uses: asottile/workflows/.github/workflows/tox.yml@v1.0.0 + uses: asottile/workflows/.github/workflows/tox.yml@v1.5.0 with: - env: '["py37", "py38", "py39", "py310"]' + env: '["py38", "py39", "py310", "py311"]' os: ubuntu-latest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8938e897..5b99fc5d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,24 +10,23 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.3.0 + rev: v2.4.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports rev: v3.10.0 hooks: - id: reorder-python-imports - args: [--py37-plus, --add-import, 'from __future__ import annotations'] + args: [--py38-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v2.5.1 + rev: v3.0.0 hooks: - id: add-trailing-comma - args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.7.0 + rev: v3.8.0 hooks: - id: pyupgrade - args: [--py37-plus] + args: [--py38-plus] - repo: https://github.com/pre-commit/mirrors-autopep8 rev: v2.0.2 hooks: diff --git a/setup.cfg b/setup.cfg index 1603c7dc..b72aa645 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,7 +21,7 @@ packages = find: install_requires = ruamel.yaml>=0.15 tomli>=1.1.0;python_version<"3.11" -python_requires = >=3.7 +python_requires = >=3.8 [options.packages.find] exclude = diff --git a/tox.ini b/tox.ini index cb2b92ab..11340f4d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,pypy3,pre-commit +envlist = py,pre-commit [testenv] deps = -rrequirements-dev.txt From e432efb74bd4d5f55b688282c7d5720a47297311 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 1 Jul 2023 17:35:45 -0400 Subject: [PATCH 282/334] shlex.join is always available in 3.8+ --- pre_commit_hooks/destroyed_symlinks.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pre_commit_hooks/destroyed_symlinks.py b/pre_commit_hooks/destroyed_symlinks.py index 88253c0b..f2569085 100644 --- a/pre_commit_hooks/destroyed_symlinks.py +++ b/pre_commit_hooks/destroyed_symlinks.py @@ -76,11 +76,7 @@ def main(argv: Sequence[str] | None = None) -> int: for destroyed_link in destroyed_links: print(f'- {destroyed_link}') print('You should unstage affected files:') - print( - '\tgit reset HEAD -- {}'.format( - ' '.join(shlex.quote(link) for link in destroyed_links), - ), - ) + print(f'\tgit reset HEAD -- {shlex.join(destroyed_links)}') print( 'And retry commit. As a long term solution ' 'you may try to explicitly tell git that your ' From 249f51528745bcbac39b6e137c2833b77e2aa8f1 Mon Sep 17 00:00:00 2001 From: Abel Soares Siqueira Date: Fri, 7 Jul 2023 12:45:16 +0200 Subject: [PATCH 283/334] Fix missing file-contents-sorter options in the README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9751c00b..1ebba89f 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,10 @@ Sort the lines in specified files (defaults to alphabetical). You must provide the target [`files`](https://pre-commit.com/#config-files) as input. Note that this hook WILL remove blank lines and does NOT respect any comments. +The following arguments are available: +- `--ignore-case` - fold lower case to upper case characters. +- `--unique` - ensure each line is unique. + #### `fix-byte-order-marker` removes UTF-8 byte order marker @@ -125,10 +129,6 @@ removes UTF-8 byte order marker Add `# -*- coding: utf-8 -*-` to the top of python files. - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) -The following arguments are available: -- `--ignore-case` - fold lower case to upper case characters. -- `--unique` - ensure each line is unique. - #### `forbid-new-submodules` Prevent addition of new git submodules. From a87e8bc6451436264fa21a2d755223765151d494 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 05:21:06 +0000 Subject: [PATCH 284/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.8.0 → v3.9.0](https://github.com/asottile/pyupgrade/compare/v3.8.0...v3.9.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5b99fc5d..b8e6f001 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.8.0 + rev: v3.9.0 hooks: - id: pyupgrade args: [--py38-plus] From 268a93037bb241a5cafb0203b85b9208908313e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Sun, 23 Jul 2023 05:28:40 +0200 Subject: [PATCH 285/334] Fix a typo in check_yaml --- pre_commit_hooks/check_yaml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 250794ef..95633476 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -46,7 +46,7 @@ def main(argv: Sequence[str] | None = None) -> int: '--unsafe', action='store_true', help=( 'Instead of loading the files, simply parse them for syntax. ' - 'A syntax-only check enables extensions and unsafe contstructs ' + 'A syntax-only check enables extensions and unsafe constructs ' 'which would otherwise be forbidden. Using this option removes ' 'all guarantees of portability to other yaml implementations. ' 'Implies --allow-multiple-documents' From 8cd2371e27663e823cf25e7e181fc2e1ecfa48b1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 07:08:59 +0000 Subject: [PATCH 286/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/add-trailing-comma: v3.0.0 → v3.0.1](https://github.com/asottile/add-trailing-comma/compare/v3.0.0...v3.0.1) - [github.com/asottile/pyupgrade: v3.9.0 → v3.10.1](https://github.com/asottile/pyupgrade/compare/v3.9.0...v3.10.1) - [github.com/PyCQA/flake8: 6.0.0 → 6.1.0](https://github.com/PyCQA/flake8/compare/6.0.0...6.1.0) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b8e6f001..10808c31 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,11 +19,11 @@ repos: - id: reorder-python-imports args: [--py38-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v3.0.0 + rev: v3.0.1 hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.9.0 + rev: v3.10.1 hooks: - id: pyupgrade args: [--py38-plus] @@ -32,7 +32,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy From bc7973eb59b55310fecaef51c785edf5923b5957 Mon Sep 17 00:00:00 2001 From: mwip Date: Wed, 2 Aug 2023 15:47:15 +0200 Subject: [PATCH 287/334] Add bpdb to debug_statements_hook This patch adds the bpython debugger import `bpdb` to the debug_statements_hook. --- pre_commit_hooks/debug_statement_hook.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pre_commit_hooks/debug_statement_hook.py b/pre_commit_hooks/debug_statement_hook.py index 9ada657a..cf544c7b 100644 --- a/pre_commit_hooks/debug_statement_hook.py +++ b/pre_commit_hooks/debug_statement_hook.py @@ -8,6 +8,7 @@ DEBUG_STATEMENTS = { + 'bpdb', 'ipdb', 'pdb', 'pdbr', From fdbaeb81fa95240c840741cf1192bcdf1cddebf3 Mon Sep 17 00:00:00 2001 From: Roel Adriaans Date: Sat, 5 Aug 2023 22:56:46 +0200 Subject: [PATCH 288/334] Fix blank lines As stated in the documentation: `Note that this hook WILL remove blank lines` Previously this hook would always add blank a blank line. With this fix, if the file is empty, a newline will not be added, and multpline blanklines in a file will be removed. Fixes #935 --- pre_commit_hooks/file_contents_sorter.py | 5 ++++- tests/file_contents_sorter_test.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index c5691f0b..02bdbccf 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -37,7 +37,10 @@ def sort_file_contents( after = sorted(lines, key=key) before_string = b''.join(before) - after_string = b'\n'.join(after) + b'\n' + after_string = b'\n'.join(after) + + if after_string: + after_string += b'\n' if before_string == after_string: return PASS diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py index 5e79e401..49b3b793 100644 --- a/tests/file_contents_sorter_test.py +++ b/tests/file_contents_sorter_test.py @@ -10,7 +10,9 @@ @pytest.mark.parametrize( ('input_s', 'argv', 'expected_retval', 'output'), ( - (b'', [], FAIL, b'\n'), + (b'', [], PASS, b''), + (b'\n', [], FAIL, b''), + (b'\n\n', [], FAIL, b''), (b'lonesome\n', [], PASS, b'lonesome\n'), (b'missing_newline', [], FAIL, b'missing_newline\n'), (b'newline\nmissing', [], FAIL, b'missing\nnewline\n'), From 7b72d56327f09de0c8721c89a3e7e964ef1b0cc5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 06:03:44 +0000 Subject: [PATCH 289/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.4.1 → v1.5.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.4.1...v1.5.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 10808c31..36dc0aba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.4.1 + rev: v1.5.0 hooks: - id: mypy additional_dependencies: [types-all] From 98c67bd3b5dd33c3cb31479e81f70aa3f5ef825a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 06:16:07 +0000 Subject: [PATCH 290/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.5.0 → v1.5.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.0...v1.5.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 36dc0aba..28c627a0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.0 + rev: v1.5.1 hooks: - id: mypy additional_dependencies: [types-all] From baa6589e9d226537d3da1c6d21ecfa74185e042a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 05:38:18 +0000 Subject: [PATCH 291/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-autopep8: v2.0.2 → v2.0.4](https://github.com/pre-commit/mirrors-autopep8/compare/v2.0.2...v2.0.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28c627a0..8657e75e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v2.0.2 + rev: v2.0.4 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From 7bf53fac3498f5b62f042f5f71875ceafc7178ac Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 06:46:56 +0000 Subject: [PATCH 292/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/add-trailing-comma: v3.0.1 → v3.1.0](https://github.com/asottile/add-trailing-comma/compare/v3.0.1...v3.1.0) - https://github.com/pre-commit/mirrors-autopep8 → https://github.com/hhatto/autopep8 --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8657e75e..99d4b38d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - id: reorder-python-imports args: [--py38-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v3.0.1 + rev: v3.1.0 hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade @@ -27,7 +27,7 @@ repos: hooks: - id: pyupgrade args: [--py38-plus] -- repo: https://github.com/pre-commit/mirrors-autopep8 +- repo: https://github.com/hhatto/autopep8 rev: v2.0.4 hooks: - id: autopep8 From 95e2fe33af04cbd1fe3952172bb18e8058516d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Wed, 6 Sep 2023 17:01:03 +0000 Subject: [PATCH 293/334] Document newline behavior of `file-contents-sorter` --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1ebba89f..50892273 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ Makes sure files end in a newline and only a newline. Sort the lines in specified files (defaults to alphabetical). You must provide the target [`files`](https://pre-commit.com/#config-files) as input. Note that this hook WILL remove blank lines and does NOT respect any comments. +All newlines will be converted to line feeds (`\n`). The following arguments are available: - `--ignore-case` - fold lower case to upper case characters. From 0837e0aede40309f8a7bfc57b3ca730741180ee2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 07:06:39 +0000 Subject: [PATCH 294/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder-python-imports: v3.10.0 → v3.11.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.11.0) - [github.com/asottile/pyupgrade: v3.10.1 → v3.11.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.11.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 99d4b38d..26812a9f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports - rev: v3.10.0 + rev: v3.11.0 hooks: - id: reorder-python-imports args: [--py38-plus, --add-import, 'from __future__ import annotations'] @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 + rev: v3.11.0 hooks: - id: pyupgrade args: [--py38-plus] From 2e4efef07eedd0c8cafd5f424c66a768fedcbfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= <6774676+eumiro@users.noreply.github.com> Date: Thu, 21 Sep 2023 19:54:38 +0200 Subject: [PATCH 295/334] Remove redundant int() conversion --- pre_commit_hooks/check_added_large_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/check_added_large_files.py b/pre_commit_hooks/check_added_large_files.py index 79c8d4e3..9e0619b0 100644 --- a/pre_commit_hooks/check_added_large_files.py +++ b/pre_commit_hooks/check_added_large_files.py @@ -46,7 +46,7 @@ def find_large_added_files( filenames_filtered &= added_files() for filename in filenames_filtered: - kb = int(math.ceil(os.stat(filename).st_size / 1024)) + kb = math.ceil(os.stat(filename).st_size / 1024) if kb > maxkb: print(f'{filename} ({kb} KB) exceeds {maxkb} KB.') retv = 1 From 30f4ca331f333ac400658458deee17d3decf7a85 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 07:23:59 +0000 Subject: [PATCH 296/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.11.0 → v3.13.0](https://github.com/asottile/pyupgrade/compare/v3.11.0...v3.13.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26812a9f..58a08f2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.11.0 + rev: v3.13.0 hooks: - id: pyupgrade args: [--py38-plus] From 038e3dd9648bc24f95498b5e99186c792dba400d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 08:58:19 +0000 Subject: [PATCH 297/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v2.4.0 → v2.5.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.4.0...v2.5.0) - [github.com/asottile/reorder-python-imports: v3.11.0 → v3.12.0](https://github.com/asottile/reorder-python-imports/compare/v3.11.0...v3.12.0) - [github.com/asottile/pyupgrade: v3.13.0 → v3.14.0](https://github.com/asottile/pyupgrade/compare/v3.13.0...v3.14.0) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58a08f2a..7e8acac8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,11 +10,11 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.4.0 + rev: v2.5.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports - rev: v3.11.0 + rev: v3.12.0 hooks: - id: reorder-python-imports args: [--py38-plus, --add-import, 'from __future__ import annotations'] @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.13.0 + rev: v3.14.0 hooks: - id: pyupgrade args: [--py38-plus] From f27ee318d2388b6e19ddc3e5281b5f09e261bcaf Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 7 Oct 2023 13:50:33 -0400 Subject: [PATCH 298/334] don't rewrite string quotes inside f-strings --- pre_commit_hooks/string_fixer.py | 15 ++++++++++++++- tests/string_fixer_test.py | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/string_fixer.py b/pre_commit_hooks/string_fixer.py index 0ef9bc7a..d1b1c4ae 100644 --- a/pre_commit_hooks/string_fixer.py +++ b/pre_commit_hooks/string_fixer.py @@ -3,9 +3,16 @@ import argparse import io import re +import sys import tokenize from typing import Sequence +if sys.version_info >= (3, 12): # pragma: >=3.12 cover + FSTRING_START = tokenize.FSTRING_START + FSTRING_END = tokenize.FSTRING_END +else: # pragma: <3.12 cover + FSTRING_START = FSTRING_END = -1 + START_QUOTE_RE = re.compile('^[a-zA-Z]*"') @@ -40,11 +47,17 @@ def fix_strings(filename: str) -> int: # Basically a mutable string splitcontents = list(contents) + fstring_depth = 0 + # Iterate in reverse so the offsets are always correct tokens_l = list(tokenize.generate_tokens(io.StringIO(contents).readline)) tokens = reversed(tokens_l) for token_type, token_text, (srow, scol), (erow, ecol), _ in tokens: - if token_type == tokenize.STRING: + if token_type == FSTRING_START: # pragma: >=3.12 cover + fstring_depth += 1 + elif token_type == FSTRING_END: # pragma: >=3.12 cover + fstring_depth -= 1 + elif fstring_depth == 0 and token_type == tokenize.STRING: new_text = handle_match(token_text) splitcontents[ line_offsets[srow] + scol: diff --git a/tests/string_fixer_test.py b/tests/string_fixer_test.py index 9dd73152..8eb164c5 100644 --- a/tests/string_fixer_test.py +++ b/tests/string_fixer_test.py @@ -37,6 +37,12 @@ 1, ), ('"foo""bar"', "'foo''bar'", 1), + pytest.param( + "f'hello{\"world\"}'", + "f'hello{\"world\"}'", + 0, + id='ignore nested fstrings', + ), ) From c4a0b883114b00d8d76b479c820ce7950211c99b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 7 Oct 2023 14:04:19 -0400 Subject: [PATCH 299/334] v4.5.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 24 ++++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e8acac8..d9ffea2b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d5aebf..c1daaba5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +4.5.0 - 2023-10-07 +================== + +### Features +- `requirements-txt-fixer`: also sort `constraints.txt` by default. + - #857 PR by @lev-blit. + - #830 issue by @PLPeeters. +- `debug-statements`: add `bpdb` debugger. + - #942 PR by @mwip. + - #941 issue by @mwip. + +### Fixes +- `file-contents-sorter`: fix sorting an empty file. + - #944 PR by @RoelAdriaans. + - #935 issue by @paduszyk. +- `double-quote-string-fixer`: don't rewrite inside f-strings in 3.12+. + - #973 PR by @asottile. + - #971 issue by @XuehaiPan. + +## Migrating +- now requires python >= 3.8. + - #926 PR by @asottile. + - #927 PR by @asottile. + 4.4.0 - 2022-11-23 ================== diff --git a/README.md b/README.md index 50892273..9ae7ec5b 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 # Use the ref you want to point at + rev: v4.5.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index b72aa645..6a4c459d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.4.0 +version = 4.5.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 6e0df5d9bbfd7f4ac3af9c3db4794bf8b86211b5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:33:33 +0000 Subject: [PATCH 300/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.14.0 → v3.15.0](https://github.com/asottile/pyupgrade/compare/v3.14.0...v3.15.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d9ffea2b..36f4fdc5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.14.0 + rev: v3.15.0 hooks: - id: pyupgrade args: [--py38-plus] From 82ad7d5ecad1840d2f970c7446e977ab56fa363a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 20:03:39 +0000 Subject: [PATCH 301/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.5.1 → v1.6.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.1...v1.6.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 36f4fdc5..0d5b9dad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.1 + rev: v1.6.0 hooks: - id: mypy additional_dependencies: [types-all] From 81954a7ca6c2318e62759569d6e6797b0d3cee9c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 20:28:12 +0000 Subject: [PATCH 302/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.6.0 → v1.6.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.6.0...v1.6.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0d5b9dad..960ac136 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.0 + rev: v1.6.1 hooks: - id: mypy additional_dependencies: [types-all] From d0d3f3ac05a91dc59a3feabcc95003d71c26837c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 20:35:42 +0000 Subject: [PATCH 303/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.6.1 → v1.7.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.6.1...v1.7.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 960ac136..d16a857c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.1 + rev: v1.7.0 hooks: - id: mypy additional_dependencies: [types-all] From 34b4ce86854df4ee038667a36a5cc0b5a1b9ef59 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:01:20 +0000 Subject: [PATCH 304/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.7.0 → v1.7.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.0...v1.7.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d16a857c..42cf2ab3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.0 + rev: v1.7.1 hooks: - id: mypy additional_dependencies: [types-all] From 8212857ada298050090a5ae3fd11cdc019ebb9e0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 20:20:03 +0000 Subject: [PATCH 305/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.7.1 → v1.8.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.1...v1.8.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42cf2ab3..b2752cc3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.1 + rev: v1.8.0 hooks: - id: mypy additional_dependencies: [types-all] From 8e040424dc5d61d6d0a85ed2fe8c0f640052a4b8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:21:22 +0000 Subject: [PATCH 306/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 6.1.0 → 7.0.0](https://github.com/PyCQA/flake8/compare/6.1.0...7.0.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b2752cc3..87c0a527 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy From 16f5239fab35115f71941bf3328923e135a21e8f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 00:02:27 +0000 Subject: [PATCH 307/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.15.0 → v3.15.1](https://github.com/asottile/pyupgrade/compare/v3.15.0...v3.15.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 87c0a527..777d1984 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.1 hooks: - id: pyupgrade args: [--py38-plus] From 0d6d0a79dfef62c27f7d614f02cbb08da2a07896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Houlbr=C3=A8que?= Date: Wed, 21 Feb 2024 14:22:08 +0100 Subject: [PATCH 308/334] Remove duplicated packages --- pre_commit_hooks/requirements_txt_fixer.py | 11 ++++++++++- tests/requirements_txt_fixer_test.py | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 58843940..261acc97 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -45,6 +45,11 @@ def __lt__(self, requirement: Requirement) -> bool: elif requirement.value == b'\n': return False else: + # if 2 requirements have the same name, the one with comments + # needs to go first (so that when removing duplicates, the one + # with comments is kept) + if self.name == requirement.name: + return bool(self.comments) > bool(requirement.comments) return self.name < requirement.name def is_complete(self) -> bool: @@ -113,10 +118,14 @@ def fix_requirements(f: IO[bytes]) -> int: if req.value != b'pkg-resources==0.0.0\n' ] + # sort the requirements and remove duplicates + prev = None for requirement in sorted(requirements): after.extend(requirement.comments) assert requirement.value, requirement.value - after.append(requirement.value) + if prev is None or requirement.value != prev.value: + after.append(requirement.value) + prev = requirement after.extend(rest) after_string = b''.join(after) diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index b725afa2..c400be1f 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -68,6 +68,12 @@ b'f<=2\n' b'g<2\n', ), + (b'a==1\nb==1\na==1\n', FAIL, b'a==1\nb==1\n'), + ( + b'a==1\nb==1\n#comment about a\na==1\n', + FAIL, + b'#comment about a\na==1\nb==1\n', + ), (b'ocflib\nDjango\nPyMySQL\n', FAIL, b'Django\nocflib\nPyMySQL\n'), ( b'-e git+ssh://git_url@tag#egg=ocflib\nDjango\nPyMySQL\n', From bda540f53c7733f81a580985e7ad8c136aa1e936 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 00:16:08 +0000 Subject: [PATCH 309/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.8.0 → v1.9.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.8.0...v1.9.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 777d1984..87e45641 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.8.0 + rev: v1.9.0 hooks: - id: mypy additional_dependencies: [types-all] From 6880fa1d4d0983c8a544a4b8c783d205649f3c51 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:47:33 +0000 Subject: [PATCH 310/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/hhatto/autopep8: v2.0.4 → v2.1.0](https://github.com/hhatto/autopep8/compare/v2.0.4...v2.1.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 87e45641..6d6d2910 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/hhatto/autopep8 - rev: v2.0.4 + rev: v2.1.0 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From 41912f6f5a1c5b7d4dec09677acb40769edf25ab Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:31:45 +0000 Subject: [PATCH 311/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.15.1 → v3.15.2](https://github.com/asottile/pyupgrade/compare/v3.15.1...v3.15.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d6d2910..3fde0d45 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.15.1 + rev: v3.15.2 hooks: - id: pyupgrade args: [--py38-plus] From eadcce2e03893cb90c5da35286855e7867bef0f7 Mon Sep 17 00:00:00 2001 From: Eric L Frederich Date: Wed, 14 Dec 2022 10:35:51 -0500 Subject: [PATCH 312/334] Stop pkg_resources from being added as well This package with an underscore instead of a dash seems to be new behavior (at least on Ubuntu 20.04 with Python 3.8) fixes #1030 --- pre_commit_hooks/requirements_txt_fixer.py | 5 ++++- tests/requirements_txt_fixer_test.py | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py index 261acc97..07b57e18 100644 --- a/pre_commit_hooks/requirements_txt_fixer.py +++ b/pre_commit_hooks/requirements_txt_fixer.py @@ -115,7 +115,10 @@ def fix_requirements(f: IO[bytes]) -> int: # which is automatically added by broken pip package under Debian requirements = [ req for req in requirements - if req.value != b'pkg-resources==0.0.0\n' + if req.value not in [ + b'pkg-resources==0.0.0\n', + b'pkg_resources==0.0.0\n', + ] ] # sort the requirements and remove duplicates diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py index c400be1f..c0d2c65d 100644 --- a/tests/requirements_txt_fixer_test.py +++ b/tests/requirements_txt_fixer_test.py @@ -82,6 +82,8 @@ ), (b'bar\npkg-resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'), (b'foo\npkg-resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'), + (b'bar\npkg_resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'), + (b'foo\npkg_resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'), ( b'git+ssh://git_url@tag#egg=ocflib\nDjango\nijk\n', FAIL, From cef973f323866a506a07b9e4ebe76685095de4f9 Mon Sep 17 00:00:00 2001 From: Max R Date: Tue, 2 Apr 2024 11:11:58 -0400 Subject: [PATCH 313/334] Add deprecation messaging for `fix-encoding-pragma` --- .pre-commit-hooks.yaml | 2 +- README.md | 3 +++ pre_commit_hooks/fix_encoding_pragma.py | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index c0d811ca..4b4d0cf2 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -145,7 +145,7 @@ language: python types: [text] - id: fix-encoding-pragma - name: fix python encoding pragma + name: fix python encoding pragma (deprecated) description: 'adds # -*- coding: utf-8 -*- to the top of python files.' language: python entry: fix-encoding-pragma diff --git a/README.md b/README.md index 9ae7ec5b..ee959fd8 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,9 @@ The following arguments are available: removes UTF-8 byte order marker #### `fix-encoding-pragma` + +_Deprecated since py2 is EOL - use [pyupgrade](https://github.com/asottile/pyupgrade) instead._ + Add `# -*- coding: utf-8 -*-` to the top of python files. - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py index 60c71eeb..eee67058 100644 --- a/pre_commit_hooks/fix_encoding_pragma.py +++ b/pre_commit_hooks/fix_encoding_pragma.py @@ -1,6 +1,7 @@ from __future__ import annotations import argparse +import sys from typing import IO from typing import NamedTuple from typing import Sequence @@ -107,6 +108,13 @@ def _normalize_pragma(pragma: str) -> bytes: def main(argv: Sequence[str] | None = None) -> int: + print( + 'warning: this hook is deprecated and will be removed in a future ' + 'release because py2 is EOL. instead, use ' + 'https://github.com/asottile/pyupgrade', + file=sys.stderr, + ) + parser = argparse.ArgumentParser( 'Fixes the encoding pragma of python files', ) From 2c9f875913ee60ca25ce70243dc24d5b6415598c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 6 Apr 2024 14:24:38 -0400 Subject: [PATCH 314/334] v4.6.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fde0d45..937696b0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index c1daaba5..bf99d9f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +4.6.0 - 2024-04-06 +================== + +### Features +- `requirements-txt-fixer`: remove duplicate packages. + - #1014 PR by @vhoulbreque-withings. + - #960 issue @csibe17. + +### Migrating +- `fix-encoding-pragma`: deprecated -- will be removed in 5.0.0. use + [pyupgrade](https://github.com/asottile/pyupgrade) or some other tool. + - #1033 PR by @mxr. + - #1032 issue by @mxr. + 4.5.0 - 2023-10-07 ================== diff --git a/README.md b/README.md index ee959fd8..4992baf8 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 # Use the ref you want to point at + rev: v4.6.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 6a4c459d..82a5457c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.5.0 +version = 4.6.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown From 865409743e7d23dc6aa0c2faaefebbe879881ab8 Mon Sep 17 00:00:00 2001 From: Eric L Frederich Date: Thu, 22 Apr 2021 08:51:03 -0400 Subject: [PATCH 315/334] Add check for illegal Widnows names Fixes #589 --- .pre-commit-hooks.yaml | 5 +++ README.md | 3 ++ tests/check_illegal_windows_names_test.py | 46 +++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 tests/check_illegal_windows_names_test.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 4b4d0cf2..116392d1 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -40,6 +40,11 @@ language: python types: [text, executable] stages: [commit, push, manual] +- id: check-illegal-windows-names + name: check illegal windows names + entry: Illegal windows filenames detected + language: fail + files: '(?i)(^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|/|$)' - id: check-json name: check json description: checks json files for parseable syntax. diff --git a/README.md b/README.md index 4992baf8..97bfba66 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,9 @@ Checks for a common error of placing code before the docstring. #### `check-executables-have-shebangs` Checks that non-binary executables have a proper shebang. +#### `check-illegal-windows-names` +Check for files that cannot be created on Windows. + #### `check-json` Attempts to load all json files to verify syntax. diff --git a/tests/check_illegal_windows_names_test.py b/tests/check_illegal_windows_names_test.py new file mode 100644 index 00000000..4dce4f6b --- /dev/null +++ b/tests/check_illegal_windows_names_test.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +import os.path +import re + +import pytest + +from pre_commit_hooks.check_yaml import yaml + + +@pytest.fixture(scope='module') +def hook_re(): + here = os.path.dirname(__file__) + with open(os.path.join(here, '..', '.pre-commit-hooks.yaml')) as f: + hook_defs = yaml.load(f) + hook, = ( + hook + for hook in hook_defs + if hook['id'] == 'check-illegal-windows-names' + ) + yield re.compile(hook['files']) + + +@pytest.mark.parametrize( + 's', + ( + pytest.param('aux.txt', id='with ext'), + pytest.param('aux', id='without ext'), + pytest.param('AuX.tXt', id='capitals'), + pytest.param('com7.dat', id='com with digit'), + ), +) +def test_check_illegal_windows_names_matches(hook_re, s): + assert hook_re.search(s) + + +@pytest.mark.parametrize( + 's', + ( + pytest.param('README.md', id='standard file'), + pytest.param('foo.aux', id='as ext'), + pytest.param('com.dat', id='com without digit'), + ), +) +def test_check_illegal_windows_names_does_not_match(hook_re, s): + assert hook_re.search(s) is None From 714f1e57b18e12cfccab2a34697c42c895f58886 Mon Sep 17 00:00:00 2001 From: Eric L Frederich Date: Tue, 16 Apr 2024 14:43:15 -0400 Subject: [PATCH 316/334] support more illegal Windows filenames See comments in #1031 --- .pre-commit-hooks.yaml | 2 +- tests/check_illegal_windows_names_test.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 116392d1..44a8648d 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -44,7 +44,7 @@ name: check illegal windows names entry: Illegal windows filenames detected language: fail - files: '(?i)(^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|/|$)' + files: '(?i)((^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|/|$)|:)' - id: check-json name: check json description: checks json files for parseable syntax. diff --git a/tests/check_illegal_windows_names_test.py b/tests/check_illegal_windows_names_test.py index 4dce4f6b..35a5be3b 100644 --- a/tests/check_illegal_windows_names_test.py +++ b/tests/check_illegal_windows_names_test.py @@ -28,6 +28,8 @@ def hook_re(): pytest.param('aux', id='without ext'), pytest.param('AuX.tXt', id='capitals'), pytest.param('com7.dat', id='com with digit'), + pytest.param(':', id='bare colon'), + pytest.param('file:Zone.Identifier', id='mid colon'), ), ) def test_check_illegal_windows_names_matches(hook_re, s): From 25cdd5457b6548ecf02d6935f52f86c446e6a2d4 Mon Sep 17 00:00:00 2001 From: Alex Marvin Date: Fri, 12 Apr 2024 15:22:10 -0500 Subject: [PATCH 317/334] Continues processing JSONs even if hook fails (fixes #1038) --- pre_commit_hooks/pretty_format_json.py | 22 +++++++++++++--------- tests/pretty_format_json_test.py | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index 627a11cc..5c0292bf 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -115,16 +115,20 @@ def main(argv: Sequence[str] | None = None) -> int: f'Input File {json_file} is not a valid JSON, consider using ' f'check-json', ) - return 1 - - if contents != pretty_contents: - if args.autofix: - _autofix(json_file, pretty_contents) - else: - diff_output = get_diff(contents, pretty_contents, json_file) - sys.stdout.buffer.write(diff_output.encode()) - status = 1 + else: + if contents != pretty_contents: + if args.autofix: + _autofix(json_file, pretty_contents) + else: + diff_output = get_diff( + contents, + pretty_contents, + json_file, + ) + sys.stdout.buffer.write(diff_output.encode()) + + status = 1 return status diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 5ded724a..68b6d7a1 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -82,6 +82,24 @@ def test_autofix_main(tmpdir): assert ret == 0 +def test_invalid_main(tmpdir): + srcfile1 = tmpdir.join('not_valid_json.json') + srcfile1.write( + '{\n' + ' // not json\n' + ' "a": "b"\n' + '}', + ) + srcfile2 = tmpdir.join('to_be_json_formatted.json') + srcfile2.write('{ "a": "b" }') + + # it should have skipped the first file and formatted the second one + assert main(['--autofix', str(srcfile1), str(srcfile2)]) == 1 + + # confirm second file was formatted (shouldn't trigger linter again) + assert main([str(srcfile2)]) == 0 + + def test_orderfile_get_pretty_format(): ret = main(( '--top-keys=alist', get_resource_path('pretty_formatted_json.json'), From fcbfb901ead82504a20ec5e3760c528d23f60057 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 22:03:55 +0000 Subject: [PATCH 318/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.9.0 → v1.10.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.9.0...v1.10.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 937696b0..54719348 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.9.0 + rev: v1.10.0 hooks: - id: mypy additional_dependencies: [types-all] From a508c71a29a1b1e287a99bc56500eeee48db8549 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 21:34:23 +0000 Subject: [PATCH 319/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/hhatto/autopep8: v2.1.0 → v2.1.1](https://github.com/hhatto/autopep8/compare/v2.1.0...v2.1.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 54719348..5d222eb9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/hhatto/autopep8 - rev: v2.1.0 + rev: v2.1.1 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From b06e32ef419102dbb417bc25a3f5dd45f4e41bff Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 21:46:58 +0000 Subject: [PATCH 320/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/reorder-python-imports: v3.12.0 → v3.13.0](https://github.com/asottile/reorder-python-imports/compare/v3.12.0...v3.13.0) - [github.com/hhatto/autopep8: v2.1.1 → v2.2.0](https://github.com/hhatto/autopep8/compare/v2.1.1...v2.2.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5d222eb9..4dde6254 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports - rev: v3.12.0 + rev: v3.13.0 hooks: - id: reorder-python-imports args: [--py38-plus, --add-import, 'from __future__ import annotations'] @@ -28,7 +28,7 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/hhatto/autopep8 - rev: v2.1.1 + rev: v2.2.0 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From bd4e4872472cdc5b794ecc603c70c14e57287496 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 21:56:59 +0000 Subject: [PATCH 321/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.15.2 → v3.16.0](https://github.com/asottile/pyupgrade/compare/v3.15.2...v3.16.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4dde6254..5be72cd8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.15.2 + rev: v3.16.0 hooks: - id: pyupgrade args: [--py38-plus] From b6fb5ca711190069a0dae4d3da5a34da4ffad3a9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:57:24 +0000 Subject: [PATCH 322/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/hhatto/autopep8: v2.2.0 → v2.3.0](https://github.com/hhatto/autopep8/compare/v2.2.0...v2.3.0) - [github.com/PyCQA/flake8: 7.0.0 → 7.1.0](https://github.com/PyCQA/flake8/compare/7.0.0...7.1.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5be72cd8..12ef649c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,11 +28,11 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/hhatto/autopep8 - rev: v2.2.0 + rev: v2.3.0 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 + rev: 7.1.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy From 2b5af89b173e843580939aa2970cb7bcacef3ec1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 21:49:05 +0000 Subject: [PATCH 323/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/hhatto/autopep8: v2.3.0 → v2.3.1](https://github.com/hhatto/autopep8/compare/v2.3.0...v2.3.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 12ef649c..da259a40 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/hhatto/autopep8 - rev: v2.3.0 + rev: v2.3.1 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 From f895cde3c70f16e8eb94d9e881bc3133c66bb644 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:34:16 +0000 Subject: [PATCH 324/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.10.0 → v1.10.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.10.0...v1.10.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index da259a40..7a675fca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.0 + rev: v1.10.1 hooks: - id: mypy additional_dependencies: [types-all] From 9e7917b35e1286dd1bca18f83686451093c50006 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 22:04:19 +0000 Subject: [PATCH 325/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.10.1 → v1.11.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.10.1...v1.11.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7a675fca..f869f5e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.1 + rev: v1.11.0 hooks: - id: mypy additional_dependencies: [types-all] From 282f7ae54de6a5483bb86f9c3e696df81314b59f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:59:19 +0000 Subject: [PATCH 326/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.16.0 → v3.17.0](https://github.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f869f5e6..3a4d24f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.17.0 hooks: - id: pyupgrade args: [--py38-plus] From effeb7a7431950cd5ff88c08994a326cb238a436 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:00:04 +0000 Subject: [PATCH 327/334] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pre_commit_hooks/check_executables_have_shebangs.py | 2 +- pre_commit_hooks/check_yaml.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pre_commit_hooks/check_executables_have_shebangs.py b/pre_commit_hooks/check_executables_have_shebangs.py index d8e4f490..7c984d39 100644 --- a/pre_commit_hooks/check_executables_have_shebangs.py +++ b/pre_commit_hooks/check_executables_have_shebangs.py @@ -35,7 +35,7 @@ class GitLsFile(NamedTuple): filename: str -def git_ls_files(paths: Sequence[str]) -> Generator[GitLsFile, None, None]: +def git_ls_files(paths: Sequence[str]) -> Generator[GitLsFile]: outs = cmd_output('git', 'ls-files', '-z', '--stage', '--', *paths) for out in zsplit(outs): metadata, filename = out.split('\t') diff --git a/pre_commit_hooks/check_yaml.py b/pre_commit_hooks/check_yaml.py index 95633476..01873921 100644 --- a/pre_commit_hooks/check_yaml.py +++ b/pre_commit_hooks/check_yaml.py @@ -11,7 +11,7 @@ yaml = ruamel.yaml.YAML(typ='safe') -def _exhaust(gen: Generator[str, None, None]) -> None: +def _exhaust(gen: Generator[str]) -> None: for _ in gen: pass From 2bcdd3ccffdc318fe3f1d50689e175e9d27bf0e6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 22:39:35 +0000 Subject: [PATCH 328/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/flake8: 7.1.0 → 7.1.1](https://github.com/PyCQA/flake8/compare/7.1.0...7.1.1) - [github.com/pre-commit/mirrors-mypy: v1.11.0 → v1.11.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.11.0...v1.11.1) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3a4d24f3..055e5f25 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,11 +32,11 @@ repos: hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.0 + rev: v1.11.1 hooks: - id: mypy additional_dependencies: [types-all] From 6952eeb163c50ac127d1c1b4332b54aa992a3e04 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 22:18:38 +0000 Subject: [PATCH 329/334] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.11.1 → v1.11.2](https://github.com/pre-commit/mirrors-mypy/compare/v1.11.1...v1.11.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 055e5f25..deac5564 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.1 + rev: v1.11.2 hooks: - id: mypy additional_dependencies: [types-all] From 6553d02eb916232e19604c4c7415f35535f25328 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 26 Aug 2024 19:24:42 -0400 Subject: [PATCH 330/334] remove types-all --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index deac5564..bca81f8c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,4 +39,3 @@ repos: rev: v1.11.2 hooks: - id: mypy - additional_dependencies: [types-all] From 003dfa55c9eb05b08b33f60864363392958f4618 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 30 Sep 2024 20:47:31 -0400 Subject: [PATCH 331/334] update stages names to the non-deprecated names --- .pre-commit-hooks.yaml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 44a8648d..c4b0b8be 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -3,7 +3,8 @@ description: prevents giant files from being committed. entry: check-added-large-files language: python - stages: [commit, push, manual] + stages: [pre-commit, pre-push, manual] + minimum_pre_commit_version: 3.2.0 - id: check-ast name: check python ast description: simply checks whether the files parse as valid python. @@ -39,7 +40,8 @@ entry: check-executables-have-shebangs language: python types: [text, executable] - stages: [commit, push, manual] + stages: [pre-commit, pre-push, manual] + minimum_pre_commit_version: 3.2.0 - id: check-illegal-windows-names name: check illegal windows names entry: Illegal windows filenames detected @@ -57,7 +59,8 @@ entry: check-shebang-scripts-are-executable language: python types: [text] - stages: [commit, push, manual] + stages: [pre-commit, pre-push, manual] + minimum_pre_commit_version: 3.2.0 - id: pretty-format-json name: pretty format json description: sets a standard for formatting json files. @@ -136,7 +139,8 @@ entry: end-of-file-fixer language: python types: [text] - stages: [commit, push, manual] + stages: [pre-commit, pre-push, manual] + minimum_pre_commit_version: 3.2.0 - id: file-contents-sorter name: file contents sorter description: sorts the lines in specified files (defaults to alphabetical). you must provide list of target files as input in your .pre-commit-config.yaml file. @@ -203,4 +207,5 @@ entry: trailing-whitespace-fixer language: python types: [text] - stages: [commit, push, manual] + stages: [pre-commit, pre-push, manual] + minimum_pre_commit_version: 3.2.0 From c7d1e85f24382186efd2c67b95891b00dc3c4505 Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Thu, 22 Aug 2024 21:30:48 +0200 Subject: [PATCH 332/334] set stages for `destroyed-symlinks` The 'destroyed-symlinks' hook runs upon 'commit-msg' hook, however when used in 'git submodules', repository scope breaks > pre_commit_hooks.util.CalledProcessError: (('git', 'status', > '--porcelain=v2', '-z', '--', '.../COMMIT_EDITMSG'), 0, 128, '', > b"fatal: .../COMMIT_EDITMSG: '...' is outside repository at '...'\n") --- Signed-off-by: Adrian DC --- .pre-commit-hooks.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index c4b0b8be..4242ef85 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -115,6 +115,7 @@ entry: destroyed-symlinks language: python types: [file] + stages: [pre-commit, pre-push, manual] - id: detect-aws-credentials name: detect aws credentials description: detects *your* aws credentials from the aws cli credentials file. From fd011242fd472708233388ea6d68964469e3a774 Mon Sep 17 00:00:00 2001 From: Jeffrey Lim Date: Thu, 25 Apr 2024 22:46:10 +0200 Subject: [PATCH 333/334] Extend check for illegal Windows filenames --- .pre-commit-hooks.yaml | 4 ++-- tests/check_illegal_windows_names_test.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 4242ef85..b71169bb 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -44,9 +44,9 @@ minimum_pre_commit_version: 3.2.0 - id: check-illegal-windows-names name: check illegal windows names - entry: Illegal windows filenames detected + entry: Illegal Windows filenames detected language: fail - files: '(?i)((^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|/|$)|:)' + files: '(?i)((^|/)(CON|PRN|AUX|NUL|COM[\d¹²³]|LPT[\d¹²³])(\.|/|$)|[<>:\"\\|?*\x00-\x1F]|/[^/]*[\.\s]/|[^/]*[\.\s]$)' - id: check-json name: check json description: checks json files for parseable syntax. diff --git a/tests/check_illegal_windows_names_test.py b/tests/check_illegal_windows_names_test.py index 35a5be3b..82d75322 100644 --- a/tests/check_illegal_windows_names_test.py +++ b/tests/check_illegal_windows_names_test.py @@ -30,6 +30,17 @@ def hook_re(): pytest.param('com7.dat', id='com with digit'), pytest.param(':', id='bare colon'), pytest.param('file:Zone.Identifier', id='mid colon'), + pytest.param('path/COM¹.json', id='com with superscript'), + pytest.param('dir/LPT³.toml', id='lpt with superscript'), + pytest.param('with < less than', id='with less than'), + pytest.param('Fast or Slow?.md', id='with question mark'), + pytest.param('with "double" quotes', id='with double quotes'), + pytest.param('with_null\x00byte', id='with null byte'), + pytest.param('ends_with.', id='ends with period'), + pytest.param('ends_with ', id='ends with space'), + pytest.param('ends_with\t', id='ends with tab'), + pytest.param('dir/ends./with.txt', id='directory ends with period'), + pytest.param('dir/ends /with.txt', id='directory ends with space'), ), ) def test_check_illegal_windows_names_matches(hook_re, s): @@ -42,6 +53,10 @@ def test_check_illegal_windows_names_matches(hook_re, s): pytest.param('README.md', id='standard file'), pytest.param('foo.aux', id='as ext'), pytest.param('com.dat', id='com without digit'), + pytest.param('.python-version', id='starts with period'), + pytest.param(' pseudo nan', id='with spaces'), + pytest.param('!@#$%^&;=≤\'~`¡¿€🤗', id='with allowed characters'), + pytest.param('path.to/file.py', id='standard path'), ), ) def test_check_illegal_windows_names_does_not_match(hook_re, s): From cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 5 Oct 2024 14:42:33 -0400 Subject: [PATCH 334/334] v5.0.0 --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 24 ++++++++++++++++++++++++ README.md | 2 +- setup.cfg | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bca81f8c..315c420a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/CHANGELOG.md b/CHANGELOG.md index bf99d9f4..e1655740 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +5.0.0 - 2024-10-05 +================== + +### Features +- `requirements-txt-fixer`: also remove `pkg_resources==...`. + - #850 PR by @ericfrederich. + - #1030 issue by @ericfrederich. +- `check-illegal-windows-names`: new hook! + - #1044 PR by @ericfrederich. + - #589 issue by @ericfrederich. + - #1049 PR by @Jeffrey-Lim. +- `pretty-format-json`: continue processing even if a file has a json error. + - #1039 PR by @amarvin. + - #1038 issue by @amarvin. + +### Fixes +- `destroyed-symlinks`: set `stages` to `[pre-commit, pre-push, manual]` + - PR #1085 by @AdrianDC. + +### Migrating +- pre-commit-hooks now requires `pre-commit>=3.2.0`. +- use non-deprecated names for `stages`. + - #1093 PR by @asottile. + 4.6.0 - 2024-04-06 ================== diff --git a/README.md b/README.md index 97bfba66..c0f678fd 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml` ```yaml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 # Use the ref you want to point at + rev: v5.0.0 # Use the ref you want to point at hooks: - id: trailing-whitespace # - id: ... diff --git a/setup.cfg b/setup.cfg index 82a5457c..a0d67f82 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit_hooks -version = 4.6.0 +version = 5.0.0 description = Some out-of-the-box hooks for pre-commit. long_description = file: README.md long_description_content_type = text/markdown