[[linter]] code = 'FLAKE8' include_patterns = ['**/*.py'] exclude_patterns = [ '.git/**', 'build_test_custom_build/**', 'build/**', 'caffe2/**', 'docs/caffe2/**', 'docs/cpp/src/**', 'docs/src/**', 'fb/**', '**/fb/**', 'functorch/docs/**', 'functorch/examples/**', 'functorch/docs/source/tutorials/**', 'torch/_inductor/fx_passes/serialized_patterns/**', 'torch/_inductor/autoheuristic/artifacts/**', 'scripts/**', 'test/generated_type_hints_smoketest.py', 'test/test_torchfuzz_repros.py', # CPython tests 'test/dynamo/cpython/**', # Tests from the NumPy test suite 'test/torch_np/numpy_test/**/*.py', 'third_party/**', 'torch/include/**', 'torch/lib/**', 'venv/**', '**/*.pyi', "tools/experimental/torchfuzz/**", 'tools/test/test_selective_build.py', ] command = [ 'python3', 'tools/linter/adapters/flake8_linter.py', '--', '@{{PATHSFILE}}' ] init_command = [ 'python3', 'tools/linter/adapters/pip_init.py', '--dry-run={{DRYRUN}}', 'flake8==7.3.0', 'flake8-bugbear==24.12.12', 'flake8-comprehensions==3.16.0', 'flake8-executable==2.1.3', 'flake8-logging-format==2024.24.12', 'flake8-pyi==25.5.0', 'flake8-simplify==0.22.0', 'mccabe==0.7.0', 'pycodestyle==2.14.0', 'pyflakes==3.4.0', 'torchfix==0.4.0 ; python_version >= "3.10" and python_version < "3.13"', ] [[linter]] code = 'CLANGFORMAT' include_patterns = [ 'aten/src/ATen/*.h', 'aten/src/ATen/cpu/vec/**/*.h', 'aten/src/ATen/mps/**/*.mm', 'aten/src/ATen/mps/**/*.h', 'aten/src/ATen/xpu/**/*.h', 'aten/src/ATen/xpu/**/*.cpp', 'aten/src/ATen/core/boxing/**/*.h', 'aten/src/ATen/core/dispatch/**/*.h', 'aten/src/ATen/core/Formatting.cpp', 'aten/src/ATen/native/mps/**/*.metal', 'aten/src/ATen/native/mps/**/*.mm', 'aten/src/ATen/native/mps/**/*.h', 'aten/src/ATen/native/vulkan/**/*.h', 'aten/src/ATen/native/vulkan/**/*.cpp', 'aten/src/ATen/native/cuda/MultiTensorApply.cuh', 'aten/src/ATen/native/**/Foreach*.*', 'aten/src/ATen/native/cuda/fused*.*', 'aten/src/ATen/native/cuda/Fused*.cu', 'aten/src/ATen/native/cudnn/*.h', 'aten/src/ATen/native/cudnn/*.cpp', 'aten/src/ATen/native/mkldnn/xpu/**/*.h', 'aten/src/ATen/native/mkldnn/xpu/**/*.cpp', 'aten/src/ATen/native/Tensor*.h', 'aten/src/ATen/native/Tensor*.cpp', 'c10/**/*.h', 'c10/**/*.cpp', 'torch/csrc/**/*.h', 'torch/csrc/**/*.hpp', 'torch/csrc/**/*.cpp', 'torch/nativert/**/*.h', 'torch/nativert/**/*.cpp', 'torch/headeronly/**/*.h', 'test/cpp/**/*.h', 'test/cpp/**/*.cpp', ] exclude_patterns = [ 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h', 'aten/src/ATen/native/mps/kernels/Quantized.metal', 'c10/util/strong_type.h', '**/fb/**', 'torch/csrc/inductor/aoti_torch/generated/**', 'torch/csrc/jit/serialization/mobile_bytecode_generated.h', 'torch/csrc/utils/pythoncapi_compat.h', 'aten/src/ATen/dlpack.h', ] init_command = [ 'python3', 'tools/linter/adapters/s3_init.py', '--config-json=tools/linter/adapters/s3_init_config.json', '--linter=clang-format', '--dry-run={{DRYRUN}}', '--output-dir=.lintbin', '--output-name=clang-format', ] command = [ 'python3', 'tools/linter/adapters/clangformat_linter.py', '--binary=.lintbin/clang-format', '--', '@{{PATHSFILE}}' ] is_formatter = true [[linter]] code = 'MYPY' include_patterns = [ 'setup.py', 'functorch/dim/**/*.py', 'torch/**/*.py', 'torch/**/*.pyi', 'caffe2/**/*.py', 'caffe2/**/*.pyi', 'test/test_bundled_images.py', 'test/test_bundled_inputs.py', 'test/test_complex.py', 'test/test_datapipe.py', 'test/test_futures.py', 'test/test_numpy_interop.py', 'test/test_torch.py', 'test/test_type_hints.py', 'test/test_type_info.py', 'test/test_utils.py', ] exclude_patterns = [ '**/fb/**', ] command = [ 'python3', 'tools/linter/adapters/mypy_linter.py', '--config=mypy.ini', '--', '@{{PATHSFILE}}' ] init_command = [ 'python3', 'tools/linter/adapters/pip_init.py', '--dry-run={{DRYRUN}}', 'numpy==1.26.4 ; python_version >= "3.10" and python_version <= "3.11"', 'numpy==2.1.0 ; python_version >= "3.12"', 'expecttest==0.3.0', 'mypy==1.16.0', 'sympy==1.13.3', 'types-requests==2.27.25', 'types-pyyaml==6.0.2', 'types-tabulate==0.8.8', 'types-protobuf==5.29.1.20250403', 'types-setuptools==79.0.0.20250422', 'types-jinja2==2.11.9', 'types-colorama==0.4.6', 'filelock==3.18.0', 'junitparser==2.1.1', 'rich==14.1.0', 'pyyaml==6.0.2', 'optree==0.13.0', 'dataclasses-json==0.6.7', 'pandas==2.2.3', ] [[linter]] code = 'MYPYSTRICT' include_patterns = [ '.github/**/*.py', 'benchmarks/instruction_counts/**/*.py', 'tools/**/*.py', 'torchgen/**/*.py', 'torch/utils/_pytree.py', 'torch/utils/_cxx_pytree.py', 'torch/utils/benchmark/utils/common.py', 'torch/utils/benchmark/utils/timer.py', 'torch/utils/benchmark/utils/valgrind_wrapper/**/*.py', ] exclude_patterns = [ # (linbinyu) copied from internal repo '**/fb/**', 'tools/code_analyzer/gen_operators_yaml.py', 'tools/dynamo/verify_dynamo.py', 'tools/gen_vulkan_spv.py', 'tools/test/gen_operators_yaml_test.py', 'tools/test/gen_oplist_test.py', 'tools/test/test_selective_build.py', 'tools/experimental/torchfuzz/**', ] command = [ 'python3', 'tools/linter/adapters/mypy_linter.py', '--config=mypy-strict.ini', '--code=MYPYSTRICT', '--', '@{{PATHSFILE}}' ] [[linter]] code = 'PYREFLY' include_patterns = [ 'torch/**/*.py', 'torch/**/*.pyi', 'torchgen/**/*.py', 'torchgen/**/*.pyi', 'functorch/**/*.py', 'functorch/**/*.pyi', ] exclude_patterns = [] command = [ 'python3', 'tools/linter/adapters/pyrefly_linter.py', '--config=pyrefly.toml', ] init_command = [ 'python3', 'tools/linter/adapters/pip_init.py', '--dry-run={{DRYRUN}}', 'numpy==2.1.0 ; python_version >= "3.12"', 'expecttest==0.3.0', 'pyrefly==0.36.2', 'sympy==1.13.3', 'types-requests==2.27.25', 'types-pyyaml==6.0.2', 'types-tabulate==0.8.8', 'types-protobuf==5.29.1.20250403', 'types-setuptools==79.0.0.20250422', 'types-jinja2==2.11.9', 'types-colorama==0.4.6', 'filelock==3.18.0', 'junitparser==2.1.1', 'rich==14.1.0', 'optree==0.17.0', 'types-openpyxl==3.1.5.20250919', 'types-python-dateutil==2.9.0.20251008' ] [[linter]] code = 'CLANGTIDY' include_patterns = [ # Enable coverage of headers in aten/src/ATen # and excluding most sub-directories for now. 'aten/src/ATen/*.h', 'aten/src/ATen/*.cpp', 'aten/src/ATen/cuda/*.cpp', 'aten/src/ATen/cpu/*.h', 'aten/src/ATen/cpu/*.cpp', 'aten/src/ATen/core/*.h', 'aten/src/ATen/core/*.cpp', 'aten/src/ATen/cudnn/*.h', 'aten/src/ATen/cudnn/*.cpp', 'aten/src/ATen/native/mkldnn/xpu/**/*.h', 'aten/src/ATen/native/mkldnn/xpu/**/*.cpp', 'aten/src/ATen/detail/*', 'aten/src/ATen/functorch/*.h', 'aten/src/ATen/functorch/*.cpp', 'aten/src/ATen/native/nested/cuda/*.cpp', 'aten/src/ATen/native/nested/cuda/*.h', 'aten/src/ATen/native/nested/*.cpp', 'aten/src/ATen/native/nested/*.h', 'c10/**/*.cpp', 'c10/**/*.h', 'torch/*.h', 'torch/_inductor/codegen/aoti_runtime/*.h', 'torch/_inductor/codegen/aoti_runtime/*.cpp', 'torch/csrc/*.h', 'torch/csrc/*.cpp', 'torch/csrc/**/*.h', 'torch/csrc/**/*.cpp', 'torch/csrc/jit/serialization/*.h', 'torch/csrc/jit/serialization/*.cpp', 'torch/nativert/*.h', 'torch/nativert/*.cpp', 'torch/nativert/**/*.h', 'torch/nativert/**/*.cpp', 'torch/headeronly/**/*.h', ] exclude_patterns = [ # The negative filters below are to exclude files that include onnx_pb.h or # caffe2_pb.h, otherwise we'd have to build protos as part of this CI job. # CUDA files are also excluded. '**/fb/**', '**/generated/**', '**/*pb.h', '**/*inl.h', 'aten/src/ATen/cpu/FlushDenormal.cpp', 'aten/src/ATen/cpu/Utils.cpp', 'aten/src/ATen/cpu/vml.h', 'aten/src/ATen/CPUFixedAllocator.h', 'aten/src/ATen/Parallel*.h', 'c10/xpu/**/*.h', 'c10/xpu/**/*.cpp', 'c10/benchmark/intrusive_ptr_benchmark.cpp', 'c10/cuda/CUDAAlgorithm.h', 'c10/util/complex_math.h', 'c10/util/complex_utils.h', 'c10/util/flat_hash_map.h', 'c10/util/logging*.h', 'c10/metal/*.h', 'c10/util/hash.h', 'c10/util/strong_type.h', 'c10/util/SmallVector.h', 'c10/util/win32-headers.h', 'c10/test/**/*.h', 'third_party/**/*', 'torch/csrc/api/include/torch/nn/modules/common.h', 'torch/csrc/api/include/torch/linalg.h', 'torch/csrc/autograd/generated/**', 'torch/csrc/distributed/**/*.cu', 'torch/csrc/distributed/c10d/WinSockUtils.hpp', 'torch/csrc/distributed/c10d/quantization/quantization_gpu.h', 'torch/csrc/dynamo/eval_frame.h', 'torch/csrc/inductor/aoti_torch/c/shim.h', 'torch/csrc/jit/**/*', 'torch/csrc/jit/serialization/mobile_bytecode_generated.h', 'torch/csrc/utils/generated_serialization_types.h', 'torch/csrc/utils/pythoncapi_compat.h', 'torch/csrc/inductor/aoti_runtime/sycl_runtime_wrappers.h', 'aten/src/ATen/ExpandBase.h', ] init_command = [ 'python3', 'tools/linter/adapters/s3_init.py', '--config-json=tools/linter/adapters/s3_init_config.json', '--linter=clang-tidy', '--dry-run={{DRYRUN}}', '--output-dir=.lintbin', '--output-name=clang-tidy', ] command = [ 'python3', 'tools/linter/adapters/clangtidy_linter.py', '--binary=.lintbin/clang-tidy', '--build_dir=./build', '--', '@{{PATHSFILE}}' ] [[linter]] code = 'TYPEIGNORE' include_patterns = ['**/*.py', '**/*.pyi'] exclude_patterns = [ 'fb/**', '**/fb/**', 'test/test_jit.py', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=# type:\s*ignore([^\[]|$)', '--linter-name=TYPEIGNORE', '--error-name=unqualified type: ignore', """--error-description=\ This line has an unqualified `type: ignore`; \ please convert it to `type: ignore[xxxx]`\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'TYPENOSKIP' include_patterns = ['mypy.ini'] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=follow_imports\s*=\s*skip', '--linter-name=TYPENOSKIP', '--error-name=use of follow_imports = skip', """--error-description=\ follow_imports = skip is forbidden from mypy.ini configuration as it \ is extremely easy to accidentally turn off type checking unintentionally. If \ you need to suppress type errors, use a top level # mypy: ignore-errors. \ Do not rely on automatic Any substitution; instead, manually # type: ignore \ at use sites or define a pyi type stub with more relaxed types. \ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'NOQA' include_patterns = ['**/*.py', '**/*.pyi'] exclude_patterns = [ 'caffe2/**', 'fb/**', '**/fb/**' ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=# noqa([^:]|$)', '--linter-name=NOQA', '--error-name=unqualified noqa', """--error-description=\ This line has an unqualified `noqa`; \ please convert it to `noqa: XXXX`\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'NATIVEFUNCTIONS' include_patterns=['aten/src/ATen/native/native_functions.yaml'] command = [ 'python3', 'tools/linter/adapters/nativefunctions_linter.py', '--native-functions-yml=aten/src/ATen/native/native_functions.yaml', ] init_command = [ 'python3', 'tools/linter/adapters/pip_init.py', '--dry-run={{DRYRUN}}', 'ruamel.yaml==0.18.10', ] is_formatter = true [[linter]] code = 'GHA' include_patterns=['.github/workflows/**/*.yml'] command = [ 'python3', 'tools/linter/adapters/gha_linter.py', '--', '@{{PATHSFILE}}' ] init_command = [ 'python3', 'tools/linter/adapters/pip_init.py', '--dry-run={{DRYRUN}}', 'ruamel.yaml==0.18.10', ] [[linter]] code = 'NEWLINE' include_patterns=['**'] exclude_patterns=[ '**/contrib/**', 'third_party/**', '**/*.bat', '**/*.expect', '**/*.ipynb', '**/*.ps1', '**/*.ptl', 'fb/**', '**/fb/**', 'tools/clang_format_hash/**', 'test/cpp/jit/upgrader_models/*.ptl', 'test/cpp/jit/upgrader_models/*.ptl.ff', 'test/dynamo/cpython/**', '**/*.png', '**/*.gz', '**/*.patch', ] command = [ 'python3', 'tools/linter/adapters/newlines_linter.py', '--', '@{{PATHSFILE}}', ] is_formatter = true [[linter]] code = 'SPACES' include_patterns = ['**'] exclude_patterns = [ '**/contrib/**', '**/*.diff', '**/*.patch', 'third_party/**', 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h', 'fb/**', '**/fb/**', 'test/cpp/jit/upgrader_models/*.ptl', 'test/cpp/jit/upgrader_models/*.ptl.ff', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=[[:blank:]]$', '--linter-name=SPACES', '--error-name=trailing spaces', '--replace-pattern=s/[[:blank:]]+$//', """--error-description=\ This line has trailing spaces; please remove them.\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'TABS' include_patterns = ['**'] exclude_patterns = [ '**/*.svg', '**/*Makefile', '**/contrib/**', 'third_party/**', '**/.gitattributes', '**/.gitmodules', 'fb/**', '**/fb/**', 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h', 'test/cpp/jit/upgrader_models/*.ptl', 'test/cpp/jit/upgrader_models/*.ptl.ff', '.ci/docker/common/install_rocm_drm.sh', '.lintrunner.toml', '**/*.patch', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', # @lint-ignore TXT2 '--pattern= ', '--linter-name=TABS', '--error-name=saw some tabs', '--replace-pattern=s/\t/ /', """--error-description=\ This line has tabs; please replace them with spaces.\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'C10_UNUSED' include_patterns = [ '**/*.cpp', '**/*.h', ] exclude_patterns = [ 'torch/headeronly/macros/Macros.h', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=C10_UNUSED', '--linter-name=C10_UNUSED', '--error-name=deprecated C10_UNUSED macro', '--replace-pattern=s/C10_UNUSED/[[maybe_unused]]/', """--error-description=\ Deprecated macro, use [[maybe_unused]] directly\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'C10_NODISCARD' include_patterns = [ '**/*.cpp', '**/*.h', ] exclude_patterns = [ 'torch/headeronly/macros/Macros.h', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=C10_NODISCARD', '--linter-name=C10_NODISCARD', '--error-name=deprecated C10_NODISCARD macro', '--replace-pattern=s/C10_NODISCARD/[[nodiscard]]/', """--error-description=\ Deprecated macro, use [[nodiscard]] directly\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'INCLUDE' include_patterns = [ 'c10/**', 'aten/**', 'torch/csrc/**', 'torch/nativert/**', ] exclude_patterns = [ 'aten/src/ATen/native/quantized/cpu/qnnpack/**', 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h', 'aten/src/ATen/native/vulkan/glsl/**', '**/fb/**', 'torch/csrc/jit/serialization/mobile_bytecode_generated.h', 'torch/csrc/utils/pythoncapi_compat.h', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=#include "', '--linter-name=INCLUDE', '--error-name=quoted include', '--replace-pattern=s/#include "(.*)"$/#include <\1>/', """--error-description=\ This #include uses quotes; please convert it to #include \ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'PYBIND11_INCLUDE' include_patterns = [ '**/*.cpp', '**/*.h', ] exclude_patterns = [ 'torch/csrc/utils/pybind.h', 'torch/utils/benchmark/utils/valgrind_wrapper/compat_bindings.cpp', 'caffe2/**/*', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=#include ', '--linter-name=PYBIND11_INCLUDE', '--match-first-only', '--error-name=direct include of pybind11', # https://stackoverflow.com/a/33416489/23845 # NB: this won't work if the pybind11 include is on the first line; # but that's fine because it will just mean the lint will still fail # after applying the change and you will have to fix it manually '--replace-pattern=1,/(#include \n\1/', """--error-description=\ This #include directly includes pybind11 without also including \ #include ; this means some important \ specializations may not be included.\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'ERROR_PRONE_ISINSTANCE' include_patterns = [ 'torch/_refs/**/*.py', 'torch/_prims/**/*.py', 'torch/_prims_common/**/*.py', 'torch/_decomp/**/*.py', 'torch/_meta_registrations.py', ] exclude_patterns = [ '**/fb/**', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=isinstance\([^)]+(int|float)\)', '--linter-name=ERROR_PRONE_ISINSTANCE', '--error-name=error prone isinstance', """--error-description=\ This line has an isinstance call that directly refers to \ int or float. This is error-prone because you may also \ have wanted to allow SymInt or SymFloat in your test. \ To suppress this lint, use an appropriate type alias defined \ in torch._prims_common; use IntLike/FloatLike when you would accept \ both regular and symbolic numbers, Dim for ints representing \ dimensions, or IntWithoutSymInt/FloatWithoutSymFloat if you really \ meant to exclude symbolic numbers. """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'PYBIND11_SPECIALIZATION' include_patterns = [ '**/*.cpp', '**/*.h', ] exclude_patterns = [ # The place for all orphan specializations 'torch/csrc/utils/pybind.h', # These specializations are non-orphan 'torch/csrc/distributed/c10d/init.cpp', 'torch/csrc/jit/python/pybind.h', 'fb/**', '**/fb/**', # These are safe to exclude as they do not have Python 'c10/**/*', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=PYBIND11_DECLARE_HOLDER_TYPE', '--linter-name=PYBIND11_SPECIALIZATION', '--error-name=pybind11 specialization in non-standard location', """--error-description=\ This pybind11 specialization (PYBIND11_DECLARE_HOLDER_TYPE) should \ be placed in torch/csrc/utils/pybind.h so that it is guaranteed to be \ included at any site that may potentially make use of it via py::cast. \ If your specialization is in the same header file as the definition \ of the holder type, you can ignore this lint by adding your header to \ the exclude_patterns for this lint in .lintrunner.toml. For more \ information see https://github.com/pybind/pybind11/issues/4099 \ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'PYPIDEP' include_patterns = ['.github/**'] exclude_patterns = [ '**/*.rst', '**/*.py', '**/*.md', '**/*.diff', '**/fb/**', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', """--pattern=\ (pip|pip3|python -m pip|python3 -m pip|python3 -mpip|python -mpip) \ install ([a-zA-Z0-9][A-Za-z0-9\\._\\-]+)([^/=<>~!]+)[A-Za-z0-9\\._\\-\\*\\+\\!]*$\ """, '--linter-name=PYPIDEP', '--error-name=unpinned PyPI install', """--error-description=\ This line has unpinned PyPi installs; \ please pin them to a specific version: e.g. 'thepackage==1.2'\ """, '--', '@{{PATHSFILE}}' ] [[linter]] code = 'EXEC' include_patterns = ['**'] exclude_patterns = [ 'third_party/**', 'torch/bin/**', '**/*.so', '**/*.py', '**/*.sh', '**/*.bash', '**/git-pre-commit', '**/git-clang-format', '**/gradlew', 'fb/**', '**/fb/**', ] command = [ 'python3', 'tools/linter/adapters/exec_linter.py', '--', '@{{PATHSFILE}}', ] [[linter]] code = 'CUBINCLUDE' include_patterns = ['aten/**'] exclude_patterns = [ 'aten/src/ATen/cuda/cub*.cuh', '**/fb/**', ] command = [ 'python3', 'tools/linter/adapters/grep_linter.py', '--pattern=#include