diff --git a/.circleci/config.yml b/.circleci/config.yml index 81b50fffd54..ea4d09a7855 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -109,7 +109,19 @@ jobs: - run: command: | pip install --user --progress-bar off flake8 typing - flake8 . + flake8 --config=setup.cfg . + + python_type_check: + docker: + - image: circleci/python:3.7 + steps: + - checkout + - run: + command: | + pip install --user --progress-bar off numpy mypy + pip install --user --progress-bar off --pre torch -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html + pip install --user --progress-bar off . + mypy --config-file mypy.ini clang_format: docker: @@ -702,12 +714,14 @@ workflows: python_version: "3.6" cu_version: "cu101" - python_lint + - python_type_check - clang_format nightly: jobs: - circleci_consistency - python_lint + - python_type_check - clang_format - binary_linux_wheel: cu_version: cpu diff --git a/.circleci/config.yml.in b/.circleci/config.yml.in index 4138dca50e7..6241f9c9c28 100644 --- a/.circleci/config.yml.in +++ b/.circleci/config.yml.in @@ -109,7 +109,19 @@ jobs: - run: command: | pip install --user --progress-bar off flake8 typing - flake8 . + flake8 --config=setup.cfg . + + python_type_check: + docker: + - image: circleci/python:3.7 + steps: + - checkout + - run: + command: | + pip install --user --progress-bar off numpy mypy + pip install --user --progress-bar off --pre torch -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html + pip install --user --progress-bar off . + mypy --config-file mypy.ini clang_format: docker: @@ -398,6 +410,7 @@ workflows: python_version: "3.6" cu_version: "cu101" - python_lint + - python_type_check - clang_format nightly: @@ -405,5 +418,6 @@ workflows: jobs: - circleci_consistency - python_lint + - python_type_check - clang_format {{ workflows(prefix="nightly_", filter_branch="nightly", upload=True) }} diff --git a/.gitignore b/.gitignore index 5f483c84327..6bea8609b93 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ htmlcov *.swp *.swo gen.yml +.mypy_cache diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000000..c0d6fbb0840 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,30 @@ +[mypy] + +files = torchvision +show_error_codes = True +pretty = True + +[mypy-torchvision.datasets.*] + +ignore_errors = True + +[mypy-torchvision.io.*] + +ignore_errors = True + +[mypy-torchvision.models.*] + +ignore_errors = True + +[mypy-torchvision.ops.*] + +ignore_errors = True + +[mypy-torchvision.transforms.*] + +ignore_errors = True + +[mypy-PIL] + +ignore_missing_imports = True + diff --git a/setup.cfg b/setup.cfg index 5b77b5fbce3..19f6d24056a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,5 +9,5 @@ max-line-length = 120 [flake8] max-line-length = 120 -ignore = F401,E402,F403,W503,W504 +ignore = F401,E402,F403,W503,W504,F821 exclude = venv diff --git a/torchvision/io/_video_opt.py b/torchvision/io/_video_opt.py index da37c66cfa4..7dfa48e0af6 100644 --- a/torchvision/io/_video_opt.py +++ b/torchvision/io/_video_opt.py @@ -84,7 +84,8 @@ def __init__(self): def _validate_pts(pts_range): - # type: (List[int]) + # type: (List[int]) -> None + if pts_range[1] > 0: assert ( pts_range[0] <= pts_range[1] diff --git a/torchvision/utils.py b/torchvision/utils.py index 9ee3e31c240..be373138c5f 100644 --- a/torchvision/utils.py +++ b/torchvision/utils.py @@ -1,4 +1,4 @@ -from typing import Union, Optional, Sequence, Tuple, Text, BinaryIO +from typing import Union, Optional, List, Tuple, Text, BinaryIO import io import pathlib import torch @@ -7,7 +7,7 @@ def make_grid( - tensor: Union[torch.Tensor, Sequence[torch.Tensor]], + tensor: Union[torch.Tensor, List[torch.Tensor]], nrow: int = 8, padding: int = 2, normalize: bool = False, @@ -91,15 +91,17 @@ def norm_range(t, range): for x in irange(xmaps): if k >= nmaps: break - grid.narrow(1, y * height + padding, height - padding)\ - .narrow(2, x * width + padding, width - padding)\ - .copy_(tensor[k]) + # Tensor.copy_() is a valid method but seems to be missing from the stubs + # https://pytorch.org/docs/stable/tensors.html#torch.Tensor.copy_ + grid.narrow(1, y * height + padding, height - padding).narrow( # type: ignore[attr-defined] + 2, x * width + padding, width - padding + ).copy_(tensor[k]) k = k + 1 return grid def save_image( - tensor: Union[torch.Tensor, Sequence[torch.Tensor]], + tensor: Union[torch.Tensor, List[torch.Tensor]], fp: Union[Text, pathlib.Path, BinaryIO], nrow: int = 8, padding: int = 2,