Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply typing to all of pre-commit-hooks #360

Merged
merged 1 commit into from
Feb 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -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-*
7 changes: 6 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist: xenial
language: python
matrix:
include: # These should match the tox env list
Expand All @@ -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:
Expand Down
11 changes: 7 additions & 4 deletions get-git-lfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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/'
Expand All @@ -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
Expand All @@ -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__':
Expand Down
12 changes: 12 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion pre_commit_hooks/autopep8_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
9 changes: 7 additions & 2 deletions pre_commit_hooks/check_added_large_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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()
Expand All @@ -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='*',
Expand Down
6 changes: 4 additions & 2 deletions pre_commit_hooks/check_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -34,4 +36,4 @@ def check_ast(argv=None):


if __name__ == '__main__':
exit(check_ast())
exit(main())
34 changes: 20 additions & 14 deletions pre_commit_hooks/check_builtin_literals.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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
Expand All @@ -47,31 +54,30 @@ 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)
visitor.visit(tree)
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(
Expand Down
4 changes: 3 additions & 1 deletion pre_commit_hooks/check_byte_order_marker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 7 additions & 3 deletions pre_commit_hooks/check_case_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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='*',
Expand Down
5 changes: 4 additions & 1 deletion pre_commit_hooks/check_docstring_first.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import argparse
import io
import tokenize
from typing import Optional
from typing import Sequence


NON_CODE_TOKENS = frozenset((
Expand All @@ -13,6 +15,7 @@


def check_docstring_first(src, filename='<unknown>'):
# type: (str, str) -> int
"""Returns nonzero if the source has what looks like a docstring that is
not at the beginning of the source.

Expand Down Expand Up @@ -50,7 +53,7 @@ def check_docstring_first(src, filename='<unknown>'):
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)
Expand Down
10 changes: 8 additions & 2 deletions pre_commit_hooks/check_executables_have_shebangs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
Expand All @@ -38,3 +40,7 @@ def main(argv=None):
retv |= check_has_shebang(filename)

return retv


if __name__ == '__main__':
exit(main())
6 changes: 4 additions & 2 deletions pre_commit_hooks/check_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -22,4 +24,4 @@ def check_json(argv=None):


if __name__ == '__main__':
sys.exit(check_json())
sys.exit(main())
9 changes: 6 additions & 3 deletions pre_commit_hooks/check_merge_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import argparse
import os.path
from typing import Optional
from typing import Sequence


CONFLICT_PATTERNS = [
b'<<<<<<< ',
Expand All @@ -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
(
Expand All @@ -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')
Expand All @@ -47,4 +50,4 @@ def detect_merge_conflict(argv=None):


if __name__ == '__main__':
exit(detect_merge_conflict())
exit(main())
Loading