diff --git a/.github/scripts/convert_lintrunner_annotations_to_github.py b/.github/scripts/convert_lintrunner_annotations_to_github.py deleted file mode 100644 index 11901bc300e..00000000000 --- a/.github/scripts/convert_lintrunner_annotations_to_github.py +++ /dev/null @@ -1,63 +0,0 @@ -import json -import subprocess -import sys - -from enum import Enum -from pathlib import Path -from typing import NamedTuple, Optional - -# From: https://docs.github.com/en/rest/reference/checks -class GitHubAnnotationLevel(str, Enum): - NOTICE = "notice" - WARNING = "warning" - FAILURE = "failure" - - -class GitHubAnnotation(NamedTuple): - path: str - start_line: int - end_line: int - start_column: Optional[int] - end_column: Optional[int] - annotation_level: GitHubAnnotationLevel - message: str - title: Optional[str] - raw_details: Optional[str] - -PYTORCH_ROOT = Path(subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).decode('ascii').strip()) - -annotations = [] -for line in sys.stdin: - lint_message = json.loads(line) - - path = lint_message.get("path") - line = lint_message.get("line") - - - code = lint_message["code"] - severity = lint_message["severity"] - name = lint_message["name"] - description = lint_message.get("description") - - # These fields are required by the GitHub API, but optional in lintrunner. - # If they don't exist, just skip. - if path is None or line is None: - print(f"No path/line for lint: ({code}) {name}", file=sys.stderr) - continue - - # normalize path relative to git root - path = Path(path).relative_to(PYTORCH_ROOT) - - annotations.append(GitHubAnnotation( - path=str(path), - start_line=int(line), - end_line=int(line), - start_column=None, - end_column=None, - annotation_level=GitHubAnnotationLevel.FAILURE, - message=description, - title=f"({code}) {name}", - raw_details=None, - )._asdict()) - -print(json.dumps(annotations), flush=True) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6a4dbbf68a9..228cd84d88d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,72 +7,6 @@ on: pull_request: jobs: - lintrunner: - runs-on: ubuntu-18.04 - steps: - - name: Setup Python - uses: actions/setup-python@v2 - with: - python-version: 3.8 - architecture: x64 - - - name: Checkout PyTorch - uses: pytorch/pytorch/.github/actions/checkout-pytorch@master - with: - submodules: false - - - name: Install lintrunner - run: pip install lintrunner==0.5.* - - - name: Initialize lint dependencies - run: lintrunner init - - - name: Do build steps necessary for linters - run: | - python3 -m tools.linter.clang_tidy.generate_build_files - python3 -m tools.generate_torch_version --is_debug=false - python3 -m tools.pyi.gen_pyi \ - --native-functions-path aten/src/ATen/native/native_functions.yaml \ - --deprecated-functions-path "tools/autograd/deprecated.yaml" - - - name: Run lintrunner on all files - if: github.event_name == 'push' - run: lintrunner -vv --paths-cmd='git grep -Il .' --force-color - - - name: Run lintrunner on PR files - if: github.event_name == 'pull_request' - env: - PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} - PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} - run: | - MERGE_BASE=$(git merge-base "$PR_BASE_SHA" "$PR_HEAD_SHA") - lintrunner -vv --force-color --revision "${MERGE_BASE}" - echo "" - echo -e "\e[1m\e[36mYou can reproduce these results locally by using \`lintrunner\`.\e[0m" - echo -e "\e[1m\e[36mSee https://github.com/pytorch/pytorch/wiki/lintrunner for setup instructions.\e[0m" - - - name: Store annotations - # Don't run on forked pull requests - if: failure() && github.event.pull_request.head.repo.full_name == github.repository - run: | - lintrunner --json \ - | python .github/scripts/convert_lintrunner_annotations_to_github.py \ - > annotations.json - - cat annotations.json - - - name: Add annotations - # Don't run on forked pull requests - if: failure() && github.event.pull_request.head.repo.full_name == github.repository - uses: pytorch/add-annotations-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - check_name: 'lintrunner' - linter_output_path: annotations.json - commit_sha: ${{ github.event.pull_request.head.sha }} - mode: json - quick-checks: name: quick-checks runs-on: ubuntu-18.04 @@ -94,16 +28,70 @@ jobs: - name: Install requirements id: requirements run: pip3 install -r requirements.txt --user + - name: Ensure consistent CircleCI YAML config + if: ${{ always() && steps.requirements.outcome == 'success' }} + run: cd .circleci && ./ensure-consistency.py + - name: Lint native_functions.yaml + if: ${{ always() && steps.requirements.outcome == 'success' }} + run: | + pip3 install ruamel.yaml==0.17.4 --user + .github/scripts/lint_native_functions.py + - name: Ensure correct trailing newlines + if: ${{ always() && steps.requirements.outcome == 'success' }} + run: | + (! git --no-pager grep -Il '' -- . ':(exclude)**/contrib/**' ':(exclude)third_party' ':(exclude)**.expect' ':(exclude)**.ipynb' ':(exclude)tools/clang_format_hash' | tools/linter/trailing_newlines.py || (echo "The above files do not have correct trailing newlines; please normalize them"; false)) + - name: Ensure no trailing spaces + if: always() + run: | + (! git --no-pager grep -In '[[:blank:]]$' -- . ':(exclude)**/contrib/**' ':(exclude)**.diff' ':(exclude)third_party' || (echo "The above lines have trailing spaces; please remove them"; false)) + - name: Ensure no tabs + if: always() + run: | + (! git --no-pager grep -In $'\t' -- . ':(exclude)*.svg' ':(exclude)**Makefile' ':(exclude)**/contrib/**' ':(exclude)third_party' ':(exclude).gitattributes' ':(exclude).gitmodules' || (echo "The above lines have tabs; please convert them to spaces"; false)) - name: Ensure no non-breaking spaces if: always() run: | # NB: We use 'printf' below rather than '\u000a' since bash pre-4.2 # does not support the '\u000a' syntax (which is relevant for local linters) (! git --no-pager grep -In "$(printf '\xC2\xA0')" -- . || (echo "The above lines have non-breaking spaces (U+00A0); please convert them to spaces (U+0020)"; false)) + - name: Ensure canonical include + if: always() + run: | + (! git --no-pager grep -In $'#include "' -- ./c10 ./aten ./torch/csrc ':(exclude)aten/src/ATen/native/quantized/cpu/qnnpack/**' ':(exclude)torch/csrc/jit/serialization/mobile_bytecode_generated.h'|| (echo "The above lines have include with quotes; please convert them to #include "; false)) - name: Ensure no versionless Python shebangs if: always() run: | (! git --no-pager grep -In '#!.*python$' -- . || (echo "The above lines have versionless Python shebangs; please specify either python2 or python3"; false)) + - name: Ensure no unqualified noqa + if: always() + run: | + # shellcheck disable=SC2016 + (! git --no-pager grep -InP '# noqa(?!: [A-Z]+\d{3})' -- '**.py' '**.pyi' ':(exclude)caffe2' || (echo 'The above lines have unqualified `noqa`; please convert them to `noqa: XXXX`'; false)) + - name: Ensure no unqualified type ignore + if: always() + run: | + # shellcheck disable=SC2016 + (! git --no-pager grep -InP '# type:\s*ignore(?!\[)' -- '**.py' '**.pyi' ':(exclude)test/test_jit.py' || (echo 'The above lines have unqualified `type: ignore`; please convert them to `type: ignore[xxxx]`'; false)) + - name: Ensure GitHub PyPi dependencies are pinned + if: always() + run: | + (! git --no-pager grep --color=always -InP \ + '(pip|pip3|python -m pip|python3 -m pip|python3 -mpip|python -mpip) install ([a-z][\.a-z-0-9]*+(?!(=|.*\.whl))([[:blank:]]|))+' \ + -- .github \ + ':(exclude)**.rst' \ + ':(exclude)**.py' \ + ':(exclude)**.md' \ + ':(exclude)**.diff' \ + ':(exclude)third_party' || + (echo "The above lines have unpinned PyPi installs; please pin them to a specific version: e.g. 'thepackage==1.2'"; false)) + # note that this next step depends on a clean checkout; + # if you run it locally then it will likely to complain + # about all the generated files in torch/test + - name: Ensure C++ source files are not executable + if: always() + run: | + # shellcheck disable=SC2016 + (! find . \( -path ./third_party -o -path ./.git -o -path ./torch/bin -o -path ./build \) -prune -o -type f -executable -regextype posix-egrep -not -regex '.+(\.(bash|sh|py|so)|git-pre-commit|git-clang-format|gradlew)$' -print | grep . || (echo 'The above files have executable permission; please remove their executable permission by using `chmod -x`'; false)) - name: C++ docs check if: ${{ always() && steps.requirements.outcome == 'success' }} run: | @@ -114,12 +102,86 @@ jobs: run: | set -eux python torch/testing/_check_kernel_launches.py |& tee "${GITHUB_WORKSPACE}"/cuda_kernel_launch_checks.txt + - name: Ensure no direct cub include + if: always() + run: | + (! git --no-pager grep -I -no $'#include commit-sha.txt + - name: Install dependencies + run: | + set -eux + pip3 install typing-extensions==3.10 --user # for tools/linter/translate_annotations.py + pip3 install -r requirements-flake8.txt --user + flake8 --version + - name: Run flake8 + run: | + set -eux + flake8 | tee "${GITHUB_WORKSPACE}"/flake8-output.txt + - name: Translate annotations + if: ${{ github.event_name == 'pull_request' }} + env: + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + tools/linter/translate_annotations.py \ + --file="${GITHUB_WORKSPACE}"/flake8-output.txt \ + --regex='^(?P.*?):(?P\d+):(?P\d+): (?P\w+\d+) (?P.*)' \ + --commit="$HEAD_SHA" \ + > flake8-output/annotations.json + - name: Fail if there were any warnings + run: | + set -eu + # Re-output flake8 status so GitHub logs show it on the step that actually failed + cat "${GITHUB_WORKSPACE}"/flake8-output.txt + if [ -s "${GITHUB_WORKSPACE}"/flake8-output.txt ]; then + echo 'Please fix the above Flake8 warnings.' + false + fi + - name: Add annotations + # Don't run on forked pull requests + if: ${{ failure() && github.event.pull_request.head.repo.full_name == github.repository }} + uses: pytorch/add-annotations-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + check_name: 'flake8-py3' + linter_output_path: flake8-output/annotations.json + commit_sha: ${{ github.event.pull_request.head.sha }} + mode: json + + clang-tidy: + name: clang-tidy + runs-on: [self-hosted, linux.2xlarge] + container: + # ubuntu20.04-cuda11.2-py3.8-tidy11 + image: ghcr.io/pytorch/cilint-clang-tidy:d8f0c777964d0dd8a147360de80aed1a13eb613a + steps: + - name: Clean workspace + run: | + rm -rf "${GITHUB_WORKSPACE}" + mkdir "${GITHUB_WORKSPACE}" + # [see note: pytorch repo ref] + # deep clone (fetch-depth 0) to allow tools/linter/clang_tidy.py to do its thing + - name: Checkout PyTorch + uses: pytorch/pytorch/.github/actions/checkout-pytorch@master + with: + no-sudo: true + submodules: false + - name: Prepare output dir with HEAD commit SHA + env: + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + cd "${GITHUB_WORKSPACE}" + mkdir clang-tidy-output + cd clang-tidy-output + echo "$HEAD_SHA" > commit-sha.txt + - name: Fetch PR diff + if: ${{ github.event_name == 'pull_request' }} + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + cd "${GITHUB_WORKSPACE}" + wget -O pr.diff "https://patch-diff.githubusercontent.com/raw/pytorch/pytorch/pull/$PR_NUMBER.diff" + - name: Generate build files + run: | + cd "${GITHUB_WORKSPACE}" + python3 -m tools.linter.clang_tidy.generate_build_files + - name: Run PR clang-tidy + if: ${{ github.event_name == 'pull_request' }} + run: | + cd "${GITHUB_WORKSPACE}" + + # The Docker image has our custom build, so we don't need to install it + python3 -m tools.linter.clang_tidy \ + --clang-tidy-exe "$(which clang-tidy)" \ + --diff-file pr.diff \ + --disable-progress-bar 2>&1 | tee "${GITHUB_WORKSPACE}"/clang-tidy-output.txt + + # Run clang-tidy on a smaller subset of the codebase on master until we + # make the repository clang-tidy clean + - name: Run master clang-tidy + run: | + cd "${GITHUB_WORKSPACE}" + + python3 -m tools.linter.clang_tidy \ + --paths \ + torch/csrc/cuda \ + torch/csrc/fx \ + torch/csrc/utils \ + torch/csrc/generic \ + torch/csrc/deploy \ + torch/csrc/onnx \ + torch/csrc/tensor \ + --clang-tidy-exe "$(which clang-tidy)" \ + --disable-progress-bar 2>&1 | tee -a "${GITHUB_WORKSPACE}"/clang-tidy-output.txt + + - name: Annotate output + if: ${{ github.event_name == 'pull_request' }} + env: + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + cd "${GITHUB_WORKSPACE}" + sed --in-place 's/^\.\.\///g' clang-tidy-output.txt + tools/linter/translate_annotations.py \ + --file=clang-tidy-output.txt \ + --regex='^(?P.*?):(?P\d+):(?P\d+): (?P.*?) \[(?P.*)\]' \ + --commit="$HEAD_SHA" \ + > clang-tidy-output/annotations.json + - name: Check for warnings + run: | + cd "${GITHUB_WORKSPACE}" + set -eu + cat "${GITHUB_WORKSPACE}"/clang-tidy-output.txt + if grep -Fq "Warnings detected!" "${GITHUB_WORKSPACE}"/clang-tidy-output.txt; then + echo 'Please fix the above clang-tidy warnings.' + false + fi + - name: Add annotations + # Don't run on forked pull requests + if: ${{ failure() && github.event.pull_request.head.repo.full_name == github.repository }} + uses: pytorch/add-annotations-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + check_name: 'clang-tidy' + linter_output_path: clang-tidy/annotations.json + commit_sha: ${{ github.event.pull_request.head.sha }} + mode: json + + cmakelint: + name: cmakelint + runs-on: ubuntu-18.04 + steps: + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 3.x + architecture: x64 + # [see note: pytorch repo ref] + - name: Checkout PyTorch + uses: pytorch/pytorch/.github/actions/checkout-pytorch@master + with: + submodules: false + - name: Install dependencies + run: | + set -eux + pip3 install cmakelint==1.4.1 --user + cmakelint --version + - name: Run cmakelint + run: | + set -eux + git ls-files -z -- bootstrap '*.cmake' '*.cmake.in' '*CMakeLists.txt' | \ + grep -E -z -v '^(cmake/Modules/|cmake/Modules_CUDA_fix/|cmake/Caffe2Config.cmake.in|aten/src/ATen/ATenConfig.cmake.in|cmake/Caffe2ConfigVersion.cmake.in|cmake/TorchConfig.cmake.in|cmake/TorchConfigVersion.cmake.in|cmake/cmake_uninstall.cmake.in)' | \ + xargs -0 cmakelint --config=.cmakelintrc --spaces=2 --quiet + + mypy: + name: mypy + runs-on: ubuntu-18.04 + steps: + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + architecture: x64 + # [see note: pytorch repo ref] + - name: Checkout PyTorch + uses: pytorch/pytorch/.github/actions/checkout-pytorch@master + with: + submodules: false + - name: Install dependencies + run: | + set -eux + python3 -mpip install -r requirements.txt --user + python3 -mpip install numpy==1.20 --user # https://github.com/pytorch/pytorch/pull/60472 + python3 -mpip install expecttest==0.1.3 mypy==0.812 --user + # Needed to check tools/render_junit.py + python3 -mpip install junitparser==2.1.1 rich==10.9.0 --user + - name: Run autogen + run: | + set -eux + time python3 -mtools.generate_torch_version --is_debug=false + time python3 -mtools.codegen.gen -s aten/src/ATen -d build/aten/src/ATen + time python3 -mtools.pyi.gen_pyi --native-functions-path aten/src/ATen/native/native_functions.yaml --deprecated-functions-path "tools/autograd/deprecated.yaml" + - name: Run mypy + env: + MYPY_FORCE_COLOR: 1 + TERM: xterm-color + run: | + set -eux + STATUS= + for CONFIG in mypy*.ini; do + if ! python3 -mmypy --config="$CONFIG"; then + STATUS=fail + fi + done + if [ -n "$STATUS" ]; then + echo 'Please fix the above mypy warnings.' + false + fi + test-tools: name: Test tools if: ${{ github.repository == 'pytorch/pytorch' }} @@ -267,10 +563,6 @@ jobs: set -eux python3 -mpip install -r requirements.txt python3 -mpip install boto3==1.16.34 - pip3 install typing-extensions==3.10 --user - pip3 install -r requirements-flake8.txt --user - python3 -mpip install -r requirements.txt --user - python3 -mpip install mypy==0.812 --user make setup_lint - name: Test tools run: | diff --git a/Makefile b/Makefile index e35a5dd07df..e74f5715a82 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ # This makefile does nothing but delegating the actual building to cmake. PYTHON = python3 -PIP = pip3 all: @mkdir -p build && cd build && cmake .. $(shell $(PYTHON) ./scripts/get_python_cmake_flags.py) && $(MAKE) @@ -52,7 +51,12 @@ shellcheck: --job 'shellcheck' setup_lint: - $(PIP) install lintrunner + $(PYTHON) tools/actions_local_runner.py --file .github/workflows/lint.yml \ + --job 'flake8-py3' --step 'Install dependencies' --no-quiet + $(PYTHON) tools/actions_local_runner.py --file .github/workflows/lint.yml \ + --job 'cmakelint' --step 'Install dependencies' --no-quiet + $(PYTHON) tools/actions_local_runner.py --file .github/workflows/lint.yml \ + --job 'mypy' --step 'Install dependencies' --no-quiet $(PYTHON) tools/actions_local_runner.py --file .github/workflows/lint.yml \ --job 'shellcheck' --step 'Install Jinja2' --no-quiet @@ -67,6 +71,8 @@ setup_lint: --job 'shellcheck' --step 'Install ShellCheck' --no-quiet; \ fi $(PYTHON) -mpip install jinja2 --user + $(PYTHON) -mpip install -r tools/linter/clang_tidy/requirements.txt --user + $(PYTHON) -m tools.linter.install.clang_tidy quick_checks: # TODO: This is broken when 'git config submodule.recurse' is 'true' since the @@ -74,7 +80,41 @@ quick_checks: @$(PYTHON) tools/actions_local_runner.py \ --file .github/workflows/lint.yml \ --job 'quick-checks' \ - --step 'Ensure no versionless Python shebangs' + --step 'Ensure no trailing spaces' \ + --step 'Ensure no tabs' \ + --step 'Ensure no non-breaking spaces' \ + --step 'Ensure canonical include' \ + --step 'Ensure no versionless Python shebangs' \ + --step 'Ensure no unqualified noqa' \ + --step 'Ensure GitHub PyPi dependencies are pinned' \ + --step 'Ensure no unqualified type ignore' \ + --step 'Ensure no direct cub include' \ + --step 'Ensure correct trailing newlines' \ + --step 'Ensure no raw cuda api calls' + +flake8: + @$(PYTHON) tools/actions_local_runner.py \ + $(CHANGED_ONLY) \ + $(REF_BRANCH) \ + --job 'flake8-py3' + +mypy: + @$(PYTHON) tools/actions_local_runner.py \ + $(CHANGED_ONLY) \ + $(REF_BRANCH) \ + --job 'mypy' + +cmakelint: + @$(PYTHON) tools/actions_local_runner.py \ + --file .github/workflows/lint.yml \ + --job 'cmakelint' \ + --step 'Run cmakelint' + +clang-tidy: + @$(PYTHON) tools/actions_local_runner.py \ + $(CHANGED_ONLY) \ + $(REF_BRANCH) \ + --job 'clang-tidy' toc: @$(PYTHON) tools/actions_local_runner.py \ @@ -82,9 +122,7 @@ toc: --job 'toc' \ --step "Regenerate ToCs and check that they didn't change" -lint: quick_checks shellcheck - lintrunner +lint: flake8 mypy quick_checks cmakelint shellcheck quicklint: CHANGED_ONLY=--changed-only -quicklint: quick_checks shellcheck - lintrunner +quicklint: mypy flake8 quick_checks cmakelint shellcheck clang-tidy diff --git a/tools/extract_scripts.py b/tools/extract_scripts.py index 1090886f72d..5312ed00da1 100755 --- a/tools/extract_scripts.py +++ b/tools/extract_scripts.py @@ -58,7 +58,7 @@ def main() -> None: gha_expressions_found = False for p in Path('.github/workflows').iterdir(): - with open(p, "rb") as f: + with open(p) as f: workflow = yaml.safe_load(f) for job_name, job in workflow['jobs'].items(): diff --git a/tools/linter/adapters/pip_init.py b/tools/linter/adapters/pip_init.py index 10fdcea37ee..b4451beac64 100644 --- a/tools/linter/adapters/pip_init.py +++ b/tools/linter/adapters/pip_init.py @@ -45,7 +45,7 @@ if __name__ == "__main__": "Package {package_name} did not have a version specified. " "Please specify a version to product a consistent linting experience." ) - pip_args = ["pip3", "install"] + pip_args = ["pip3", "install", "--user"] pip_args.extend(args.packages) dry_run = args.dry_run == "1" diff --git a/tools/test/test_actions_local_runner.py b/tools/test/test_actions_local_runner.py index 3ef7c6a3c76..ba4e6fd2cdb 100644 --- a/tools/test/test_actions_local_runner.py +++ b/tools/test/test_actions_local_runner.py @@ -47,6 +47,16 @@ if sys.version_info >= (3, 8): class TestEndToEnd(unittest.TestCase): expected = [ + "cmakelint: Run cmakelint", + "quick-checks: Ensure no direct cub include", + "quick-checks: Ensure no unqualified type ignore", + "quick-checks: Ensure no unqualified noqa", + "quick-checks: Ensure canonical include", + "quick-checks: Ensure no non-breaking spaces", + "quick-checks: Ensure no tabs", + "flake8", + "quick-checks: Ensure correct trailing newlines", + "quick-checks: Ensure no trailing spaces", "shellcheck: Regenerate workflows", "shellcheck: Assert that regenerating the workflows didn't change them", "shellcheck: Extract scripts from GitHub Actions workflows", @@ -63,6 +73,8 @@ if sys.version_info >= (3, 8): for line in self.expected: self.assertIn(line, stdout) + self.assertIn("mypy", stdout) + def test_quicklint(self): cmd = ["make", "quicklint", "-j", str(multiprocessing.cpu_count())] proc = subprocess.run( @@ -73,6 +85,9 @@ if sys.version_info >= (3, 8): for line in self.expected: self.assertIn(line, stdout) + # TODO: See https://github.com/pytorch/pytorch/issues/57967 + self.assertIn("mypy (skipped typestub generation)", stdout) + class TestQuicklint(unittest.IsolatedAsyncioTestCase): test_files = [ os.path.join("caffe2", "some_cool_file.py"), @@ -132,6 +147,45 @@ if sys.version_info >= (3, 8): self.assertIn("SC2148: Tips depend on target shell", f.getvalue()) self.assertIn("SC2283: Remove spaces around = to assign", f.getvalue()) + async def test_mypy(self): + self.maxDiff = None + f = io.StringIO() + with contextlib.redirect_stdout(f): + # Quicklint assumes this has been run already and doesn't work + # without it + _, _, _ = await actions_local_runner.shell_cmd( + [ + f"{sys.executable}", + "tools/actions_local_runner.py", + "--job", + "mypy", + "--file", + ".github/workflows/lint.yml", + "--step", + "Run autogen", + ], + redirect=True, + ) + + await actions_local_runner.Mypy(self.test_py_files, True).run() + + # Should exclude the aten/ file; also, apparently mypy + # typechecks files in reverse order + expected = textwrap.dedent( + """ + x mypy (skipped typestub generation) + torch/some_stubs.pyi:3:17: error: Incompatible types in assignment (expression has type "None", variable has type "str") [assignment] + torch/some_stubs.pyi:4:17: error: Incompatible types in assignment (expression has type "float", variable has type "str") [assignment] + torch/some_cool_file.py:3:17: error: Incompatible types in assignment (expression has type "None", variable has type "str") [assignment] + torch/some_cool_file.py:4:17: error: Incompatible types in assignment (expression has type "float", variable has type "str") [assignment] + caffe2/some_cool_file.py:3:17: error: Incompatible types in assignment (expression has type "None", variable has type "str") [assignment] + caffe2/some_cool_file.py:4:17: error: Incompatible types in assignment (expression has type "float", variable has type "str") [assignment] + """ # noqa: B950 + ).lstrip( + "\n" + ) + self.assertEqual(expected, f.getvalue()) + if __name__ == "__main__": unittest.main() diff --git a/torch/csrc/jit/codegen/cuda/parser.cpp b/torch/csrc/jit/codegen/cuda/parser.cpp index 0bab90b7e4f..1e870166e71 100644 --- a/torch/csrc/jit/codegen/cuda/parser.cpp +++ b/torch/csrc/jit/codegen/cuda/parser.cpp @@ -2625,14 +2625,14 @@ class IrParser { "aten::amax/amin cannot be fused with dynamic keepdim"); TensorView* out = nullptr; - if (node->kind() == c10::Symbol::fromQualString("aten::amax")) { + if (node->kind() == + c10::Symbol::fromQualString("aten::amax")) { out = max(self->as(), dims, keepdim.value()); - } else if ( - node->kind() == c10::Symbol::fromQualString("aten::amin")) { + } else if (node->kind() == + c10::Symbol::fromQualString("aten::amin")) { out = min(self->as(), dims, keepdim.value()); } else { - TORCH_INTERNAL_ASSERT( - false, "unrecognized operation in aten::amax/amin"); + TORCH_INTERNAL_ASSERT(false, "unrecognized operation in aten::amax/amin"); } value_map.emplace(node->output()->unique(), out); },