已合并
Static checking tools and rules are adopted directly from pytorch. #33272
Jingwei Huang创建于 4月8日
Static checking tools and rules are adopted directly from pytorch. #33272
已合并
Jingwei Huang创建于 4月8日
60 个文件变更+12265-0
@@ -0,0 +1,127 @@
1+---
2+AccessModifierOffset: -1
3+AlignAfterOpenBracket: AlwaysBreak
4+AlignConsecutiveAssignments: false
5+AlignConsecutiveDeclarations: false
6+AlignEscapedNewlinesLeft: true
7+AlignOperands: false
8+AlignTrailingComments: false
9+AllowAllParametersOfDeclarationOnNextLine: false
10+AllowShortBlocksOnASingleLine: false
11+AllowShortCaseLabelsOnASingleLine: false
12+AllowShortFunctionsOnASingleLine: Empty
13+AllowShortIfStatementsOnASingleLine: false
14+AllowShortLoopsOnASingleLine: false
15+AlwaysBreakAfterReturnType: None
16+AlwaysBreakBeforeMultilineStrings: true
17+AlwaysBreakTemplateDeclarations: true
18+BinPackArguments: false
19+BinPackParameters: false
20+BraceWrapping:
21+ AfterClass: false
22+ AfterControlStatement: false
23+ AfterEnum: false
24+ AfterFunction: false
25+ AfterNamespace: false
26+ AfterObjCDeclaration: false
27+ AfterStruct: false
28+ AfterUnion: false
29+ BeforeCatch: false
30+ BeforeElse: false
31+ IndentBraces: false
32+BreakBeforeBinaryOperators: None
33+BreakBeforeBraces: Attach
34+BreakBeforeTernaryOperators: true
35+BreakConstructorInitializersBeforeComma: false
36+BreakAfterJavaFieldAnnotations: false
37+BreakStringLiterals: false
38+ColumnLimit: 80
39+CommentPragmas: '^ IWYU pragma:'
40+CompactNamespaces: false
41+ConstructorInitializerAllOnOneLineOrOnePerLine: true
42+ConstructorInitializerIndentWidth: 4
43+ContinuationIndentWidth: 4
44+Cpp11BracedListStyle: true
45+DerivePointerAlignment: false
46+DisableFormat: false
47+ForEachMacros:
48+ - FOR_EACH_RANGE
49+ - FOR_EACH
50+IncludeCategories:
51+ - Regex: '^<.*\.h(pp)?>'
52+ Priority: 1
53+ - Regex: '^<.*'
54+ Priority: 2
55+ - Regex: '.*'
56+ Priority: 3
57+IndentCaseLabels: true
58+IndentWidth: 2
59+IndentWrappedFunctionNames: false
60+KeepEmptyLinesAtTheStartOfBlocks: false
61+MacroBlockBegin: ''
62+MacroBlockEnd: ''
63+Macros:
64+ - >-
65+ PyObject_HEAD_INIT(type)={
66+ /* this is not exactly match with PyObject_HEAD_INIT in Python source code
67+ * but it is enough for clang-format */
68+ { 0xFFFFFFFF },
69+ (type)
70+ },
71+ - >-
72+ PyVarObject_HEAD_INIT(type, size)={
73+ {
74+ /* manually expand PyObject_HEAD_INIT(type) above
75+ * because clang-format do not support recursive expansion */
76+ { 0xFFFFFFFF },
77+ (type)
78+ },
79+ (size)
80+ },
81+MaxEmptyLinesToKeep: 1
82+NamespaceIndentation: None
83+PenaltyBreakBeforeFirstCallParameter: 1
84+PenaltyBreakComment: 300
85+PenaltyBreakFirstLessLess: 120
86+PenaltyBreakString: 1000
87+PenaltyExcessCharacter: 1000000
88+PenaltyReturnTypeOnItsOwnLine: 2000000
89+PointerAlignment: Left
90+ReflowComments: true
91+SortIncludes: true
92+SpaceAfterCStyleCast: false
93+SpaceBeforeAssignmentOperators: true
94+SpaceBeforeParens: ControlStatements
95+SpaceInEmptyParentheses: false
96+SpacesBeforeTrailingComments: 1
97+SpacesInAngles: false
98+SpacesInContainerLiterals: true
99+SpacesInCStyleCastParentheses: false
100+SpacesInParentheses: false
101+SpacesInSquareBrackets: false
102+Standard: c++17
103+StatementMacros:
104+ - C10_DEFINE_bool
105+ - C10_DEFINE_int
106+ - C10_DEFINE_int32
107+ - C10_DEFINE_int64
108+ - C10_DEFINE_string
109+ - C10_DEFINE_REGISTRY_WITHOUT_WARNING
110+ - C10_REGISTER_CREATOR
111+ - DEFINE_BINARY
112+ - PyObject_HEAD
113+ - PyObject_VAR_HEAD
114+ - PyException_HEAD
115+ - TORCH_DECLARE_bool
116+ 
117+TabWidth: 8
118+UseTab: Never
119+---
120+Language: ObjC
121+ColumnLimit: 120
122+AlignAfterOpenBracket: Align
123+IndentWidth: 2
124+ObjCBlockIndentWidth: 2
125+ObjCSpaceAfterProperty: false
126+ObjCSpaceBeforeProtocolList: false
127+...
@@ -0,0 +1,81 @@
1+---
2+# NOTE there must be no spaces before the '-', so put the comma last.
3+# The check bugprone-unchecked-optional-access is also turned on.
4+# Note that it can cause clang-tidy to hang randomly. The tracking issue
5+# can be found at https://github.com/llvm/llvm-project/issues/69369.
6+# When that happens, we can disable it on the problematic code by NOLINT.
7+InheritParentConfig: true
8+Checks: '
9+bugprone-*,
10+-bugprone-easily-swappable-parameters,
11+-bugprone-forward-declaration-namespace,
12+-bugprone-macro-parentheses,
13+-bugprone-lambda-function-name,
14+-bugprone-reserved-identifier,
15+-bugprone-return-const-ref-from-parameter,
16+-bugprone-swapped-arguments,
17+clang-analyzer-core.*,
18+clang-analyzer-cplusplus.*,
19+clang-analyzer-nullability.*,
20+clang-analyzer-deadcode.*,
21+clang-diagnostic-missing-prototypes,
22+cppcoreguidelines-*,
23+-cppcoreguidelines-avoid-do-while,
24+-cppcoreguidelines-avoid-magic-numbers,
25+-cppcoreguidelines-avoid-non-const-global-variables,
26+-cppcoreguidelines-interfaces-global-init,
27+-cppcoreguidelines-macro-usage,
28+-cppcoreguidelines-macro-to-enum,
29+-cppcoreguidelines-owning-memory,
30+-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
31+-cppcoreguidelines-pro-bounds-constant-array-index,
32+-cppcoreguidelines-pro-bounds-pointer-arithmetic,
33+-cppcoreguidelines-pro-type-cstyle-cast,
34+-cppcoreguidelines-pro-type-reinterpret-cast,
35+-cppcoreguidelines-pro-type-static-cast-downcast,
36+-cppcoreguidelines-pro-type-union-access,
37+-cppcoreguidelines-pro-type-vararg,
38+-cppcoreguidelines-non-private-member-variables-in-classes,
39+-facebook-hte-RelativeInclude,
40+hicpp-exception-baseclass,
41+hicpp-avoid-goto,
42+misc-*,
43+-misc-confusable-identifiers,
44+-misc-const-correctness,
45+-misc-include-cleaner,
46+-misc-use-anonymous-namespace,
47+-misc-unused-parameters,
48+-misc-no-recursion,
49+-misc-non-private-member-variables-in-classes,
50+-misc-unused-using-decls,
51+modernize-*,
52+-modernize-macro-to-enum,
53+-modernize-return-braced-init-list,
54+-modernize-use-auto,
55+-modernize-use-using,
56+-modernize-use-trailing-return-type,
57+-modernize-use-nodiscard,
58+performance-*,
59+-performance-enum-size,
60+readability-container-size-empty,
61+readability-delete-null-pointer,
62+readability-duplicate-include,
63+readability-named-parameter,
64+readability-misplaced-array-index,
65+readability-redundant*,
66+readability-simplify-subscript-expr,
67+readability-static-definition-in-anonymous-namespace
68+readability-string-compare,
69+-readability-redundant-access-specifiers,
70+-readability-redundant-control-flow,
71+-readability-redundant-inline-specifier,
72+'
73+HeaderFilterRegex: '^(aten/|c10/|torch/).*$'
74+WarningsAsErrors: '*'
75+LineFilter:
76+ - name: '/usr/include/.*'
77+CheckOptions:
78+ cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor: true
79+ cppcoreguidelines-special-member-functions.AllowImplicitlyDeletedCopyOrMove: true
80+ misc-header-include-cycle.IgnoredFilesList: 'format.h;ivalue.h;custom_class.h;Dict.h;List.h;IListRef.h'
81+...
@@ -0,0 +1 @@
1+filter=-convention/filename,-linelength,-package/consistency,-readability/logic,-readability/mixedcase,-readability/wonkycase,-syntax,-whitespace/eol,+whitespace/extra,-whitespace/indent,-whitespace/mismatch,-whitespace/newline,-whitespace/tabs
@@ -0,0 +1,36 @@
1+root = true
2+ 
3+[*]
4+charset = utf-8
5+end_of_line = lf
6+insert_final_newline = true
7+ 
8+# Python
9+[*.{py,pyi,py.in,pyi.in}]
10+indent_style = space
11+indent_size = 4
12+ 
13+# C/C++/CUDA
14+[*.{cpp,hpp,cxx,cc,c,h,cu,cuh}]
15+indent_style = space
16+indent_size = 2
17+ 
18+# Objective-C
19+[*.{mm,m,M}]
20+indent_style = space
21+indent_size = 2
22+ 
23+# Clang tools
24+[.clang-{format,tidy}]
25+indent_style = space
26+indent_size = 2
27+ 
28+# Make
29+[Makefile]
30+indent_style = tab
31+ 
32+# Batch file
33+[*.bat]
34+indent_style = space
35+indent_size = 2
36+end_of_line = crlf
A.flake8+53-0
@@ -0,0 +1,53 @@
1+[flake8]
2+# NOTE: **Mirror any changes** to this file the [tool.ruff] config in pyproject.toml
3+# before we can fully move to use ruff
4+enable-extensions = G
5+select = B,C,E,F,G,P,SIM1,SIM911,T4,W,B9
6+max-line-length = 120
7+# C408 ignored because we like the dict keyword argument syntax
8+# E501 is not flexible enough, we're using B950 instead
9+ignore =
10+ E203,E305,E402,E501,E704,E741,F405,F841,F999,W503,W504,C408,E302,W291,E303,F824,
11+ # shebang has extra meaning in fbcode lints, so I think it's not worth trying
12+ # to line this up with executable bit
13+ EXE001,
14+ # these ignores are from flake8-bugbear; please fix!
15+ B007,B008,B017,B019,B023,B028,B903,B905,B906,B907,B908,B910
16+ # these ignores are from flake8-simplify. please fix or ignore with commented reason
17+ SIM105,SIM108,SIM110,SIM111,SIM113,SIM114,SIM115,SIM116,SIM117,SIM118,SIM119,SIM12,
18+ # SIM104 is already covered by pyupgrade ruff
19+ SIM104,
20+ # flake8-simplify code styles
21+ SIM102,SIM103,SIM106,SIM112
22+per-file-ignores =
23+ __init__.py: F401
24+ test/**: F821
25+ test/**/__init__.py: F401,F821
26+ torch/utils/cpp_extension.py: B950
27+ torchgen/api/types/__init__.py: F401,F403
28+ torchgen/executorch/api/types/__init__.py: F401,F403
29+ test/dynamo/test_higher_order_ops.py: B950
30+ test/dynamo/test_error_messages.py: B950
31+ torch/testing/_internal/dynamo_test_failures.py: B950
32+ torch/__init__.py: F401
33+ torch/_prims/__init__.py: F401
34+optional-ascii-coding = True
35+exclude =
36+ ./.git,
37+ ./build_test_custom_build,
38+ ./build,
39+ ./caffe2,
40+ ./docs/caffe2,
41+ ./docs/cpp/src,
42+ ./docs/src,
43+ ./functorch/docs,
44+ ./functorch/examples,
45+ ./functorch/docs/source/tutorials,
46+ ./torch/testing/_internal/py312_intrinsics.py
47+ ./scripts,
48+ ./test/generated_type_hints_smoketest.py,
49+ ./third_party,
50+ ./torch/include,
51+ ./torch/lib,
52+ ./venv,
53+ *.pyi
@@ -0,0 +1,1806 @@
1+[[linter]]
2+code = 'FLAKE8'
3+include_patterns = ['**/*.py']
4+exclude_patterns = [
5+ '.git/**',
6+ 'build_test_custom_build/**',
7+ 'build/**',
8+ 'caffe2/**',
9+ 'docs/caffe2/**',
10+ 'docs/cpp/src/**',
11+ 'docs/src/**',
12+ 'fb/**',
13+ '**/fb/**',
14+ 'functorch/docs/**',
15+ 'functorch/examples/**',
16+ 'functorch/docs/source/tutorials/**',
17+ 'torch/_inductor/fx_passes/serialized_patterns/**',
18+ 'torch/_inductor/autoheuristic/artifacts/**',
19+ 'torch/_inductor/kernel/vendored_templates/cutedsl/kernels/**',
20+ 'torch/_inductor/kernel/vendored_templates/cutedsl/dense_blockscaled_gemm_persistent.py',
21+ 'scripts/**',
22+ 'test/generated_type_hints_smoketest.py',
23+ 'test/test_torchfuzz_repros.py',
24+ # CPython tests
25+ 'test/dynamo/cpython/**',
26+ # Tests from the NumPy test suite
27+ 'test/torch_np/numpy_test/**/*.py',
28+ 'third_party/**',
29+ 'torch/include/**',
30+ 'torch/lib/**',
31+ 'venv/**',
32+ '**/*.pyi',
33+ "tools/experimental/torchfuzz/**",
34+ 'tools/test/test_selective_build.py',
35+]
36+command = [
37+ 'uv',
38+ 'run',
39+ '--script',
40+ 'tools/linter/adapters/flake8_linter.py',
41+ '--',
42+ '@{{PATHSFILE}}'
43+]
44+ 
45+ 
46+[[linter]]
47+code = 'CLANGFORMAT'
48+include_patterns = [
49+ 'aten/src/ATen/*.h',
50+ 'aten/src/ATen/cpu/vec/**/*.h',
51+ 'aten/src/ATen/accelerator/**/*.h',
52+ 'aten/src/ATen/accelerator/**/*.cpp',
53+ 'aten/src/ATen/mps/**/*.mm',
54+ 'aten/src/ATen/mps/**/*.h',
55+ 'aten/src/ATen/xpu/**/*.h',
56+ 'aten/src/ATen/xpu/**/*.cpp',
57+ 'aten/src/ATen/core/boxing/**/*.h',
58+ 'aten/src/ATen/core/dispatch/**/*.h',
59+ 'aten/src/ATen/core/Formatting.cpp',
60+ 'aten/src/ATen/native/mps/**/*.metal',
61+ 'aten/src/ATen/native/mps/**/*.mm',
62+ 'aten/src/ATen/native/mps/**/*.h',
63+ 'aten/src/ATen/native/vulkan/**/*.h',
64+ 'aten/src/ATen/native/vulkan/**/*.cpp',
65+ 'aten/src/ATen/native/cuda/MultiTensorApply.cuh',
66+ 'aten/src/ATen/native/**/Foreach*.*',
67+ 'aten/src/ATen/native/cuda/fused*.*',
68+ 'aten/src/ATen/native/cuda/Fused*.cu',
69+ 'aten/src/ATen/native/cudnn/*.h',
70+ 'aten/src/ATen/native/cudnn/*.cpp',
71+ 'aten/src/ATen/native/mkldnn/xpu/**/*.h',
72+ 'aten/src/ATen/native/mkldnn/xpu/**/*.cpp',
73+ 'aten/src/ATen/native/Tensor*.h',
74+ 'aten/src/ATen/native/Tensor*.cpp',
75+ 'c10/**/*.h',
76+ 'c10/**/*.cpp',
77+ 'torch/csrc/**/*.h',
78+ 'torch/csrc/**/*.hpp',
79+ 'torch/csrc/**/*.cpp',
80+ 'torch/nativert/**/*.h',
81+ 'torch/nativert/**/*.cpp',
82+ 'torch/headeronly/**/*.h',
83+ 'test/cpp/**/*.h',
84+ 'test/cpp/**/*.cpp',
85+]
86+exclude_patterns = [
87+ 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h',
88+ 'aten/src/ATen/native/mps/kernels/Quantized.metal',
89+ 'c10/util/strong_type.h',
90+ '**/fb/**',
91+ 'torch/csrc/inductor/aoti_torch/generated/**',
92+ 'torch/csrc/jit/serialization/mobile_bytecode_generated.h',
93+ 'torch/csrc/utils/pythoncapi_compat.h',
94+ 'aten/src/ATen/dlpack.h',
95+]
96+init_command = [
97+ 'python3',
98+ 'tools/linter/adapters/s3_init.py',
99+ '--config-json=tools/linter/adapters/s3_init_config.json',
100+ '--linter=clang-format',
101+ '--dry-run={{DRYRUN}}',
102+ '--output-dir=.lintbin',
103+ '--output-name=clang-format',
104+]
105+command = [
106+ 'python3',
107+ 'tools/linter/adapters/clangformat_linter.py',
108+ '--binary=.lintbin/clang-format',
109+ '--',
110+ '@{{PATHSFILE}}'
111+]
112+is_formatter = true
113+ 
114+ 
115+[[linter]]
116+code = 'PYREFLY'
117+include_patterns = [
118+ 'torch/**/*.py',
119+ 'torch/**/*.pyi',
120+ 'torchgen/**/*.py',
121+ 'torchgen/**/*.pyi',
122+ 'functorch/**/*.py',
123+ 'functorch/**/*.pyi',
124+ 'tools/**/*.py',
125+ 'tools/**/*.pyi',
126+]
127+exclude_patterns = [
128+ 'torch/_inductor/kernel/vendored_templates/cutedsl/kernels/**',
129+ 'torch/_inductor/kernel/vendored_templates/cutedsl/dense_blockscaled_gemm_persistent.py',
130+]
131+command = [
132+ 'uv',
133+ 'run',
134+ '--script',
135+ 'tools/linter/adapters/pyrefly_linter.py',
136+ '--config=pyrefly.toml',
137+]
138+ 
139+[[linter]]
140+code = 'CLANGTIDY'
141+include_patterns = [
142+ # Enable coverage of headers in aten/src/ATen
143+ # and excluding most sub-directories for now.
144+ 'aten/src/ATen/*.h',
145+ 'aten/src/ATen/*.cpp',
146+ 'aten/src/ATen/cuda/*.cpp',
147+ 'aten/src/ATen/cpu/*.h',
148+ 'aten/src/ATen/cpu/*.cpp',
149+ 'aten/src/ATen/accelerator/**/*.h',
150+ 'aten/src/ATen/accelerator/**/*.cpp',
151+ 'aten/src/ATen/core/*.h',
152+ 'aten/src/ATen/core/*.cpp',
153+ 'aten/src/ATen/cudnn/*.h',
154+ 'aten/src/ATen/cudnn/*.cpp',
155+ 'aten/src/ATen/native/mkldnn/xpu/**/*.h',
156+ 'aten/src/ATen/native/mkldnn/xpu/**/*.cpp',
157+ 'aten/src/ATen/detail/*',
158+ 'aten/src/ATen/functorch/*.h',
159+ 'aten/src/ATen/functorch/*.cpp',
160+ 'aten/src/ATen/native/nested/cuda/*.cpp',
161+ 'aten/src/ATen/native/nested/cuda/*.h',
162+ 'aten/src/ATen/native/nested/*.cpp',
163+ 'aten/src/ATen/native/nested/*.h',
164+ 'aten/src/ATen/xpu/**/*.h',
165+ 'aten/src/ATen/xpu/**/*.cpp',
166+ 'c10/**/*.cpp',
167+ 'c10/**/*.h',
168+ 'torch/*.h',
169+ 'torch/_inductor/codegen/aoti_runtime/*.h',
170+ 'torch/_inductor/codegen/aoti_runtime/*.cpp',
171+ 'torch/csrc/*.h',
172+ 'torch/csrc/*.cpp',
173+ 'torch/csrc/**/*.h',
174+ 'torch/csrc/**/*.cpp',
175+ 'torch/csrc/jit/serialization/*.h',
176+ 'torch/csrc/jit/serialization/*.cpp',
177+ 'torch/nativert/*.h',
178+ 'torch/nativert/*.cpp',
179+ 'torch/nativert/**/*.h',
180+ 'torch/nativert/**/*.cpp',
181+ 'torch/headeronly/**/*.h',
182+]
183+exclude_patterns = [
184+ # The negative filters below are to exclude files that include onnx_pb.h or
185+ # caffe2_pb.h, otherwise we'd have to build protos as part of this CI job.
186+ # CUDA files are also excluded.
187+ '**/fb/**',
188+ '**/generated/**',
189+ '**/*pb.h',
190+ '**/*inl.h',
191+ 'aten/src/ATen/cpu/FlushDenormal.cpp',
192+ 'aten/src/ATen/cpu/vml.h',
193+ 'aten/src/ATen/CPUFixedAllocator.h',
194+ 'aten/src/ATen/Parallel*.h',
195+ 'c10/xpu/**/*.h',
196+ 'c10/xpu/**/*.cpp',
197+ 'c10/benchmark/intrusive_ptr_benchmark.cpp',
198+ 'c10/cuda/CUDAAlgorithm.h',
199+ 'c10/util/complex_math.h',
200+ 'c10/util/complex_utils.h',
201+ 'c10/util/flat_hash_map.h',
202+ 'c10/util/logging*.h',
203+ 'c10/metal/*.h',
204+ 'c10/util/hash.h',
205+ 'c10/util/strong_type.h',
206+ 'c10/util/SmallVector.h',
207+ 'c10/util/win32-headers.h',
208+ 'c10/test/**/*.h',
209+ 'c10/test/**/*.cpp',
210+ 'third_party/**/*',
211+ 'torch/csrc/autograd/generated/**',
212+ 'torch/csrc/distributed/**/*.cu',
213+ 'torch/csrc/distributed/c10d/WinSockUtils.hpp',
214+ 'torch/csrc/distributed/c10d/quantization/quantization_gpu.h',
215+ 'torch/csrc/dynamo/eval_frame.h',
216+ 'torch/csrc/inductor/aoti_torch/c/shim.h',
217+ 'torch/csrc/jit/**/*',
218+ 'torch/csrc/jit/serialization/mobile_bytecode_generated.h',
219+ 'torch/csrc/utils/generated_serialization_types.h',
220+ 'torch/csrc/utils/pythoncapi_compat.h',
221+ 'torch/csrc/inductor/aoti_runtime/sycl_runtime_wrappers.h',
222+]
223+init_command = [
224+ 'python3',
225+ 'tools/linter/adapters/s3_init.py',
226+ '--config-json=tools/linter/adapters/s3_init_config.json',
227+ '--linter=clang-tidy',
228+ '--dry-run={{DRYRUN}}',
229+ '--output-dir=.lintbin',
230+ '--output-name=clang-tidy',
231+]
232+command = [
233+ 'python3',
234+ 'tools/linter/adapters/clangtidy_linter.py',
235+ '--binary=.lintbin/clang-tidy',
236+ '--build_dir=./build',
237+ '--',
238+ '@{{PATHSFILE}}'
239+]
240+ 
241+[[linter]]
242+code = 'CLANGTIDY_EXECUTORCH_COMPATIBILITY'
243+include_patterns = [
244+ # c10 headers that must be C++17 compatible
245+ 'c10/macros/Export.h',
246+ 'c10/macros/Macros.h',
247+ 'c10/macros/cmake_macros.h',
248+ 'c10/util/BFloat16.h',
249+ 'c10/util/BFloat16-inl.h',
250+ 'c10/util/BFloat16-math.h',
251+ 'c10/util/Half.h',
252+ 'c10/util/Half-inl.h',
253+ 'c10/util/TypeSafeSignMath.h',
254+ 'c10/util/bit_cast.h',
255+ 'c10/util/complex.h',
256+ 'c10/util/floating_point_utils.h',
257+ 'c10/util/irange.h',
258+ 'c10/util/llvmMathExtras.h',
259+ 'c10/util/overflows.h',
260+ 'c10/util/safe_numerics.h',
261+ # torch/headeronly headers that must be C++17 compatible
262+ 'torch/headeronly/macros/cmake_macros.h',
263+ 'torch/headeronly/macros/Export.h',
264+ 'torch/headeronly/macros/Macros.h',
265+ 'torch/headeronly/util/BFloat16.h',
266+ 'torch/headeronly/util/Half.h',
267+ 'torch/headeronly/util/TypeSafeSignMath.h',
268+ 'torch/headeronly/util/bit_cast.h',
269+ 'torch/headeronly/util/complex.h',
270+ 'torch/headeronly/util/floating_point_utils.h',
271+]
272+exclude_patterns = [
273+ '**/fb/**',
274+]
275+init_command = [
276+ 'python3',
277+ 'tools/linter/adapters/s3_init.py',
278+ '--config-json=tools/linter/adapters/s3_init_config.json',
279+ '--linter=clang-tidy',
280+ '--dry-run={{DRYRUN}}',
281+ '--output-dir=.lintbin',
282+ '--output-name=clang-tidy',
283+]
284+command = [
285+ 'python3',
286+ 'tools/linter/adapters/clangtidy_linter.py',
287+ '--binary=.lintbin/clang-tidy',
288+ '--build_dir=./build',
289+ '--std=c++17',
290+ '--',
291+ '@{{PATHSFILE}}'
292+]
293+ 
294+[[linter]]
295+code = 'TYPEIGNORE'
296+include_patterns = ['**/*.py', '**/*.pyi']
297+exclude_patterns = [
298+ 'fb/**',
299+ '**/fb/**',
300+ 'test/test_jit.py',
301+]
302+command = [
303+ 'python3',
304+ 'tools/linter/adapters/grep_linter.py',
305+ '--pattern=# type:\s*ignore([^\[]|$)',
306+ '--linter-name=TYPEIGNORE',
307+ '--error-name=unqualified type: ignore',
308+ """--error-description=\
309+ This line has an unqualified `type: ignore`; \
310+ please convert it to `type: ignore[xxxx]`\
311+ """,
312+ '--',
313+ '@{{PATHSFILE}}'
314+]
315+ 
316+[[linter]]
317+code = 'TYPENOSKIP'
318+include_patterns = ['mypy.ini']
319+command = [
320+ 'python3',
321+ 'tools/linter/adapters/grep_linter.py',
322+ '--pattern=follow_imports\s*=\s*skip',
323+ '--linter-name=TYPENOSKIP',
324+ '--error-name=use of follow_imports = skip',
325+ """--error-description=\
326+ follow_imports = skip is forbidden from mypy.ini configuration as it \
327+ is extremely easy to accidentally turn off type checking unintentionally. If \
328+ you need to suppress type errors, use a top level # mypy: ignore-errors. \
329+ Do not rely on automatic Any substitution; instead, manually # type: ignore \
330+ at use sites or define a pyi type stub with more relaxed types. \
331+ """,
332+ '--',
333+ '@{{PATHSFILE}}'
334+]
335+ 
336+[[linter]]
337+code = 'NOQA'
338+include_patterns = ['**/*.py', '**/*.pyi']
339+exclude_patterns = [
340+ 'caffe2/**',
341+ 'fb/**',
342+ '**/fb/**'
343+ ]
344+command = [
345+ 'python3',
346+ 'tools/linter/adapters/grep_linter.py',
347+ '--pattern=# noqa([^:]|$)',
348+ '--linter-name=NOQA',
349+ '--error-name=unqualified noqa',
350+ """--error-description=\
351+ This line has an unqualified `noqa`; \
352+ please convert it to `noqa: XXXX`\
353+ """,
354+ '--',
355+ '@{{PATHSFILE}}'
356+]
357+ 
358+[[linter]]
359+code = 'NATIVEFUNCTIONS'
360+include_patterns=['aten/src/ATen/native/native_functions.yaml']
361+command = [
362+ 'uv',
363+ 'run',
364+ '--script',
365+ 'tools/linter/adapters/nativefunctions_linter.py',
366+ '--native-functions-yml=aten/src/ATen/native/native_functions.yaml',
367+]
368+is_formatter = true
369+ 
370+[[linter]]
371+code = 'GHA'
372+include_patterns=['.github/workflows/**/*.yml']
373+command = [
374+ 'uv',
375+ 'run',
376+ '--script',
377+ 'tools/linter/adapters/gha_linter.py',
378+ '--',
379+ '@{{PATHSFILE}}'
380+]
381+ 
382+[[linter]]
383+code = 'NEWLINE'
384+include_patterns=['**']
385+exclude_patterns=[
386+ '**/contrib/**',
387+ 'third_party/**',
388+ '**/*.bat',
389+ '**/*.expect',
390+ '**/*.ipynb',
391+ '**/*.ps1',
392+ '**/*.ptl',
393+ 'fb/**',
394+ '**/fb/**',
395+ 'tools/clang_format_hash/**',
396+ 'test/cpp/jit/upgrader_models/*.ptl',
397+ 'test/cpp/jit/upgrader_models/*.ptl.ff',
398+ 'test/dynamo/cpython/**',
399+ '**/*.png',
400+ '**/*.gz',
401+ '**/*.patch',
402+]
403+command = [
404+ 'python3',
405+ 'tools/linter/adapters/newlines_linter.py',
406+ '--',
407+ '@{{PATHSFILE}}',
408+]
409+is_formatter = true
410+ 
411+[[linter]]
412+code = 'SPACES'
413+include_patterns = ['**']
414+exclude_patterns = [
415+ '**/contrib/**',
416+ '**/*.diff',
417+ '**/*.patch',
418+ 'third_party/**',
419+ 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h',
420+ 'fb/**',
421+ '**/fb/**',
422+ 'test/cpp/jit/upgrader_models/*.ptl',
423+ 'test/cpp/jit/upgrader_models/*.ptl.ff',
424+]
425+command = [
426+ 'python3',
427+ 'tools/linter/adapters/grep_linter.py',
428+ '--pattern=[[:blank:]]$',
429+ '--linter-name=SPACES',
430+ '--error-name=trailing spaces',
431+ '--replace-pattern=s/[[:blank:]]+$//',
432+ """--error-description=\
433+ This line has trailing spaces; please remove them.\
434+ """,
435+ '--',
436+ '@{{PATHSFILE}}'
437+]
438+ 
439+[[linter]]
440+code = 'TABS'
441+include_patterns = ['**']
442+exclude_patterns = [
443+ '**/*.svg',
444+ '**/*Makefile',
445+ '**/contrib/**',
446+ 'third_party/**',
447+ '**/.gitattributes',
448+ '**/.gitmodules',
449+ 'fb/**',
450+ '**/fb/**',
451+ 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h',
452+ 'test/cpp/jit/upgrader_models/*.ptl',
453+ 'test/cpp/jit/upgrader_models/*.ptl.ff',
454+ '.ci/docker/common/install_rocm_drm.sh',
455+ '.lintrunner.toml',
456+ '**/*.patch',
457+]
458+command = [
459+ 'python3',
460+ 'tools/linter/adapters/grep_linter.py',
461+ # @lint-ignore TXT2
462+ '--pattern= ',
463+ '--linter-name=TABS',
464+ '--error-name=saw some tabs',
465+ '--replace-pattern=s/\t/ /',
466+ """--error-description=\
467+ This line has tabs; please replace them with spaces.\
468+ """,
469+ '--',
470+ '@{{PATHSFILE}}'
471+]
472+ 
473+[[linter]]
474+code = 'C10_UNUSED'
475+include_patterns = [
476+ '**/*.cpp',
477+ '**/*.h',
478+]
479+exclude_patterns = [
480+ 'torch/headeronly/macros/Macros.h',
481+]
482+command = [
483+ 'python3',
484+ 'tools/linter/adapters/grep_linter.py',
485+ '--pattern=C10_UNUSED',
486+ '--linter-name=C10_UNUSED',
487+ '--error-name=deprecated C10_UNUSED macro',
488+ '--replace-pattern=s/C10_UNUSED/[[maybe_unused]]/',
489+ """--error-description=\
490+ Deprecated macro, use [[maybe_unused]] directly\
491+ """,
492+ '--',
493+ '@{{PATHSFILE}}'
494+]
495+ 
496+[[linter]]
497+code = 'C10_NODISCARD'
498+include_patterns = [
499+ '**/*.cpp',
500+ '**/*.h',
501+]
502+exclude_patterns = [
503+ 'torch/headeronly/macros/Macros.h',
504+]
505+command = [
506+ 'python3',
507+ 'tools/linter/adapters/grep_linter.py',
508+ '--pattern=C10_NODISCARD',
509+ '--linter-name=C10_NODISCARD',
510+ '--error-name=deprecated C10_NODISCARD macro',
511+ '--replace-pattern=s/C10_NODISCARD/[[nodiscard]]/',
512+ """--error-description=\
513+ Deprecated macro, use [[nodiscard]] directly\
514+ """,
515+ '--',
516+ '@{{PATHSFILE}}'
517+]
518+ 
519+[[linter]]
520+code = 'RAWTHROW'
521+include_patterns = [
522+ '**/*.cpp',
523+ '**/*.h',
524+]
525+exclude_patterns = [
526+ # Vendored code (do not modify)
527+ 'c10/util/flat_hash_map.h',
528+ 'c10/util/order_preserving_flat_hash_map.h',
529+ 'aten/src/ATen/native/quantized/cpu/qnnpack/**',
530+ 'aten/src/ATen/native/transformers/cuda/mem_eff_attention/**',
531+ # Standalone code that cannot depend on c10
532+ 'torch/csrc/inductor/aoti_runtime/**',
533+ # Test files use EXPECT_THROW which is a gtest macro
534+ 'test/cpp/**/*.cpp',
535+]
536+command = [
537+ 'python3',
538+ 'tools/linter/adapters/grep_linter.py',
539+ '--pattern=\bthrow\b',
540+ '--allowlist-pattern=@allow-raw-throw',
541+ '--linter-name=RAWTHROW',
542+ '--error-name=raw throw statement',
543+ """--error-description=\
544+ Do not use raw `throw` in C++ code. Use TORCH_CHECK, \
545+ TORCH_CHECK_WITH, C10_THROW_ERROR, or other error-reporting macros \
546+ instead. See c10/util/Exception.h for available macros. If this is a \
547+ re-throw (throw;), restructure the code to avoid try/catch/throw or \
548+ add the file to the RAWTHROW exclude list in .lintrunner.toml with \
549+ justification.\
550+ """,
551+ '--',
552+ '@{{PATHSFILE}}'
553+]
554+ 
555+[[linter]]
556+code = 'INCLUDE'
557+include_patterns = [
558+ 'c10/**',
559+ 'aten/**',
560+ 'torch/csrc/**',
561+ 'torch/nativert/**',
562+]
563+exclude_patterns = [
564+ 'aten/src/ATen/native/quantized/cpu/qnnpack/**',
565+ 'aten/src/ATen/native/vulkan/api/vk_mem_alloc.h',
566+ 'aten/src/ATen/native/vulkan/glsl/**',
567+ '**/fb/**',
568+ 'torch/csrc/jit/serialization/mobile_bytecode_generated.h',
569+ 'torch/csrc/utils/pythoncapi_compat.h',
570+]
571+command = [
572+ 'python3',
573+ 'tools/linter/adapters/grep_linter.py',
574+ '--pattern=#include "',
575+ '--linter-name=INCLUDE',
576+ '--error-name=quoted include',
577+ '--replace-pattern=s/#include "(.*)"$/#include <\1>/',
578+ """--error-description=\
579+ This #include uses quotes; please convert it to #include <xxxx>\
580+ """,
581+ '--',
582+ '@{{PATHSFILE}}'
583+]
584+ 
585+[[linter]]
586+code = 'PYBIND11_INCLUDE'
587+include_patterns = [
588+ '**/*.cpp',
589+ '**/*.h',
590+]
591+exclude_patterns = [
592+ 'torch/csrc/utils/pybind.h',
593+ 'torch/utils/benchmark/utils/valgrind_wrapper/compat_bindings.cpp',
594+ 'caffe2/**/*',
595+]
596+command = [
597+ 'python3',
598+ 'tools/linter/adapters/grep_linter.py',
599+ '--pattern=#include <pybind11\/(^|[^(gil_simple\.h)])',
600+ '--allowlist-pattern=#include <torch\/csrc\/utils\/pybind.h>',
601+ '--linter-name=PYBIND11_INCLUDE',
602+ '--match-first-only',
603+ '--error-name=direct include of pybind11',
604+ # https://stackoverflow.com/a/33416489/23845
605+ # NB: this won't work if the pybind11 include is on the first line;
606+ # but that's fine because it will just mean the lint will still fail
607+ # after applying the change and you will have to fix it manually
608+ '--replace-pattern=1,/(#include <pybind11\/)/ s/(#include <pybind11\/)/#include <torch\/csrc\/utils\/pybind.h>\n\1/',
609+ """--error-description=\
610+ This #include directly includes pybind11 without also including \
611+ #include <torch/csrc/utils/pybind.h>; this means some important \
612+ specializations may not be included.\
613+ """,
614+ '--',
615+ '@{{PATHSFILE}}'
616+]
617+ 
618+[[linter]]
619+code = 'ERROR_PRONE_ISINSTANCE'
620+include_patterns = [
621+ 'torch/_refs/**/*.py',
622+ 'torch/_prims/**/*.py',
623+ 'torch/_prims_common/**/*.py',
624+ 'torch/_decomp/**/*.py',
625+ 'torch/_meta_registrations.py',
626+]
627+exclude_patterns = [
628+ '**/fb/**',
629+]
630+command = [
631+ 'python3',
632+ 'tools/linter/adapters/grep_linter.py',
633+ '--pattern=isinstance\([^)]+(int|float)\)',
634+ '--linter-name=ERROR_PRONE_ISINSTANCE',
635+ '--error-name=error prone isinstance',
636+ """--error-description=\
637+ This line has an isinstance call that directly refers to \
638+ int or float. This is error-prone because you may also \
639+ have wanted to allow SymInt or SymFloat in your test. \
640+ To suppress this lint, use an appropriate type alias defined \
641+ in torch._prims_common; use IntLike/FloatLike when you would accept \
642+ both regular and symbolic numbers, Dim for ints representing \
643+ dimensions, or IntWithoutSymInt/FloatWithoutSymFloat if you really \
644+ meant to exclude symbolic numbers.
645+ """,
646+ '--',
647+ '@{{PATHSFILE}}'
648+]
649+ 
650+[[linter]]
651+code = 'PYBIND11_SPECIALIZATION'
652+include_patterns = [
653+ '**/*.cpp',
654+ '**/*.h',
655+]
656+exclude_patterns = [
657+ # The place for all orphan specializations
658+ 'torch/csrc/utils/pybind.h',
659+ # These specializations are non-orphan
660+ 'torch/csrc/distributed/c10d/init.cpp',
661+ 'torch/csrc/jit/python/pybind.h',
662+ 'fb/**',
663+ '**/fb/**',
664+ # These are safe to exclude as they do not have Python
665+ 'c10/**/*',
666+]
667+command = [
668+ 'python3',
669+ 'tools/linter/adapters/grep_linter.py',
670+ '--pattern=PYBIND11_DECLARE_HOLDER_TYPE',
671+ '--linter-name=PYBIND11_SPECIALIZATION',
672+ '--error-name=pybind11 specialization in non-standard location',
673+ """--error-description=\
674+ This pybind11 specialization (PYBIND11_DECLARE_HOLDER_TYPE) should \
675+ be placed in torch/csrc/utils/pybind.h so that it is guaranteed to be \
676+ included at any site that may potentially make use of it via py::cast. \
677+ If your specialization is in the same header file as the definition \
678+ of the holder type, you can ignore this lint by adding your header to \
679+ the exclude_patterns for this lint in .lintrunner.toml. For more \
680+ information see https://github.com/pybind/pybind11/issues/4099 \
681+ """,
682+ '--',
683+ '@{{PATHSFILE}}'
684+]
685+ 
686+[[linter]]
687+code = 'PYPIDEP'
688+include_patterns = ['.github/**']
689+exclude_patterns = [
690+ '**/*.rst',
691+ '**/*.py',
692+ '**/*.md',
693+ '**/*.diff',
694+ '**/fb/**',
695+]
696+command = [
697+ 'python3',
698+ 'tools/linter/adapters/grep_linter.py',
699+ """--pattern=\
700+ (pip|pip3|python -m pip|python3 -m pip|python3 -mpip|python -mpip) \
701+ install ([a-zA-Z0-9][A-Za-z0-9\\._\\-]+)([^/=<>~!]+)[A-Za-z0-9\\._\\-\\*\\+\\!]*$\
702+ """,
703+ '--linter-name=PYPIDEP',
704+ '--error-name=unpinned PyPI install',
705+ """--error-description=\
706+ This line has unpinned PyPi installs; \
707+ please pin them to a specific version: e.g. 'thepackage==1.2'\
708+ """,
709+ '--',
710+ '@{{PATHSFILE}}'
711+]
712+ 
713+[[linter]]
714+code = 'EXEC'
715+include_patterns = ['**']
716+exclude_patterns = [
717+ 'third_party/**',
718+ 'torch/bin/**',
719+ '**/*.so',
720+ '**/*.py',
721+ '**/*.sh',
722+ '**/*.bash',
723+ '**/git-pre-commit',
724+ '**/git-clang-format',
725+ '**/gradlew',
726+ 'fb/**',
727+ '**/fb/**',
728+]
729+command = [
730+ 'python3',
731+ 'tools/linter/adapters/exec_linter.py',
732+ '--',
733+ '@{{PATHSFILE}}',
734+]
735+ 
736+[[linter]]
737+code = 'CUBINCLUDE'
738+include_patterns = ['aten/**']
739+exclude_patterns = [
740+ 'aten/src/ATen/cuda/cub*.cuh',
741+ '**/fb/**',
742+]
743+command = [
744+ 'python3',
745+ 'tools/linter/adapters/grep_linter.py',
746+ '--pattern=#include <cub/',
747+ '--linter-name=CUBINCLUDE',
748+ '--error-name=direct cub include',
749+ """--error-description=\
750+ This line has a direct cub include; please include \
751+ ATen/cuda/cub.cuh instead and wrap your cub calls in \
752+ at::native namespace if necessary.
753+ """,
754+ '--',
755+ '@{{PATHSFILE}}'
756+]
757+ 
758+[[linter]]
759+code = 'RAWCUDA'
760+include_patterns = [
761+ 'aten/**',
762+ 'c10/**',
763+]
764+exclude_patterns = [
765+ 'aten/src/ATen/test/**',
766+ 'c10/cuda/CUDAFunctions.h',
767+ 'c10/cuda/CUDACachingAllocator.cpp',
768+ '**/fb/**',
769+]
770+command = [
771+ 'python3',
772+ 'tools/linter/adapters/grep_linter.py',
773+ '--pattern=cudaStreamSynchronize',
774+ '--linter-name=RAWCUDA',
775+ '--error-name=raw CUDA API usage',
776+ """--error-description=\
777+ This line calls raw CUDA APIs directly; please use at::cuda wrappers instead.
778+ """,
779+ '--',
780+ '@{{PATHSFILE}}'
781+]
782+ 
783+[[linter]]
784+code = 'RAWCUDADEVICE'
785+include_patterns = [
786+ 'aten/**',
787+ 'c10/**',
788+ 'torch/csrc/**',
789+ 'torch/nativert/**',
790+]
791+exclude_patterns = [
792+ 'aten/src/ATen/cuda/CUDAContext.cpp',
793+ 'aten/src/ATen/cuda/CUDAGeneratorImpl.cpp',
794+ 'aten/src/ATen/test/**',
795+ 'c10/core/impl/InlineDeviceGuard.h',
796+ 'c10/cuda/CUDAFunctions.cpp',
797+ 'c10/cuda/CUDAGuard.h',
798+ 'c10/cuda/impl/CUDATest.cpp',
799+ 'torch/csrc/cuda/nccl.cpp',
800+ '**/fb/**',
801+]
802+command = [
803+ 'python3',
804+ 'tools/linter/adapters/grep_linter.py',
805+ '--pattern=(cudaSetDevice|cudaGetDevice)\\(',
806+ '--linter-name=RAWCUDADEVICE',
807+ '--error-name=raw CUDA API usage',
808+ """--error-description=\
809+ This line calls raw CUDA APIs directly; please use c10::cuda wrappers instead.
810+ """,
811+ '--',
812+ '@{{PATHSFILE}}'
813+]
814+ 
815+[[linter]]
816+code = 'ROOT_LOGGING'
817+include_patterns = [
818+ '**/*.py',
819+]
820+# These are not library code, but scripts in their own right, and so
821+# therefore are permitted to use logging
822+exclude_patterns = [
823+ 'tools/**',
824+ 'test/**',
825+ 'benchmarks/**',
826+ 'torch/distributed/run.py',
827+ 'functorch/benchmarks/**',
828+ # Grandfathered in
829+ 'caffe2/**',
830+ 'fb/**',
831+ '**/fb/**',
832+]
833+command = [
834+ 'python3',
835+ 'tools/linter/adapters/grep_linter.py',
836+ '--pattern=logging\.(debug|info|warn|warning|error|critical|log|exception)\(',
837+ '--replace-pattern=s/logging\.(debug|info|warn|warning|error|critical|log|exception)\(/log.\1(/',
838+ '--linter-name=ROOT_LOGGING',
839+ '--error-name=use of root logger',
840+ """--error-description=\
841+ Do not use root logger (logging.info, etc) directly; instead \
842+ define 'log = logging.getLogger(__name__)' and call, e.g., log.info().
843+ """,
844+ '--',
845+ '@{{PATHSFILE}}'
846+]
847+ 
848+[[linter]]
849+code = 'DEPLOY_DETECTION'
850+include_patterns = [
851+ '**/*.py',
852+]
853+command = [
854+ 'python3',
855+ 'tools/linter/adapters/grep_linter.py',
856+ '--pattern=sys\.executable == .torch_deploy.',
857+ '--replace-pattern=s/sys\.executable == .torch_deploy./torch._running_with_deploy\(\)/',
858+ '--linter-name=DEPLOY_DETECTION',
859+ '--error-name=properly detect deploy runner',
860+ """--error-description=\
861+ Do not use sys.executable to detect if running within deploy/multipy, use torch._running_with_deploy().
862+ """,
863+ '--',
864+ '@{{PATHSFILE}}'
865+]
866+ 
867+[[linter]]
868+code = 'CMAKE'
869+include_patterns = [
870+ "**/*.cmake",
871+ "**/*.cmake.in",
872+ "**/CMakeLists.txt",
873+]
874+exclude_patterns = [
875+ 'cmake/Modules/**',
876+ 'cmake/Modules_CUDA_fix/**',
877+ 'cmake/Caffe2Config.cmake.in',
878+ 'aten/src/ATen/ATenConfig.cmake.in',
879+ 'cmake/TorchConfig.cmake.in',
880+ 'cmake/TorchConfigVersion.cmake.in',
881+ 'cmake/cmake_uninstall.cmake.i',
882+ 'fb/**',
883+ '**/fb/**',
884+]
885+command = [
886+ 'uv',
887+ 'run',
888+ '--script',
889+ 'tools/linter/adapters/cmake_linter.py',
890+ '--config=.cmakelintrc',
891+ '--',
892+ '@{{PATHSFILE}}',
893+]
894+ 
895+[[linter]]
896+code = 'SHELLCHECK'
897+include_patterns = [
898+ '.ci/pytorch/**/*.sh'
899+]
900+exclude_patterns = [
901+ '**/fb/**',
902+]
903+command = [
904+ 'uv',
905+ 'run',
906+ '--script',
907+ 'tools/linter/adapters/shellcheck_linter.py',
908+ '--',
909+ '@{{PATHSFILE}}',
910+]
911+ 
912+[[linter]]
913+code = 'ACTIONLINT'
914+include_patterns = [
915+ '.github/workflows/*.yml',
916+ '.github/workflows/*.yaml',
917+ # actionlint does not support composite actions yet
918+ # '.github/actions/**/*.yml',
919+ # '.github/actions/**/*.yaml',
920+]
921+exclude_patterns = [
922+ '**/fb/**',
923+]
924+command = [
925+ 'python3',
926+ 'tools/linter/adapters/actionlint_linter.py',
927+ '--binary=.lintbin/actionlint',
928+ '--',
929+ '@{{PATHSFILE}}',
930+]
931+init_command = [
932+ 'python3',
933+ 'tools/linter/adapters/s3_init.py',
934+ '--config-json=tools/linter/adapters/s3_init_config.json',
935+ '--linter=actionlint',
936+ '--dry-run={{DRYRUN}}',
937+ '--output-dir=.lintbin',
938+ '--output-name=actionlint',
939+]
940+ 
941+[[linter]]
942+code = 'TESTOWNERS'
943+include_patterns = [
944+ 'test/**/test_*.py',
945+ 'test/**/*_test.py',
946+]
947+exclude_patterns = [
948+ 'test/run_test.py',
949+ '**/fb/**',
950+]
951+command = [
952+ 'python3',
953+ 'tools/linter/adapters/testowners_linter.py',
954+ '--',
955+ '@{{PATHSFILE}}',
956+]
957+ 
958+[[linter]]
959+code = 'TEST_HAS_MAIN'
960+include_patterns = [
961+ 'test/**/test_*.py',
962+]
963+exclude_patterns = [
964+ 'test/run_test.py',
965+ '**/fb/**',
966+ 'test/dynamo/cpython/3.13/**',
967+ 'test/quantization/**', # should be run through test/test_quantization.py
968+ 'test/jit/**', # should be run through test/test_jit.py
969+ 'test/ao/sparsity/**', # should be run through test/test_ao_sparsity.py
970+ 'test/fx/**', # should be run through test/test_fx.py
971+ 'test/package/**', # excluded by test/run_test.py
972+ 'test/distributed/argparse_util_test.py',
973+ 'test/distributed/bin/test_script.py',
974+ 'test/distributed/elastic/agent/server/test/local_elastic_agent_test.py',
975+ 'test/distributed/elastic/multiprocessing/bin/test_script.py',
976+ 'test/distributed/elastic/multiprocessing/bin/zombie_test.py',
977+ 'test/distributed/elastic/multiprocessing/errors/api_test.py',
978+ 'test/distributed/elastic/multiprocessing/errors/error_handler_test.py',
979+ 'test/distributed/elastic/multiprocessing/redirects_test.py',
980+ 'test/distributed/elastic/multiprocessing/tail_log_test.py',
981+ 'test/distributed/elastic/rendezvous/api_test.py',
982+ 'test/distributed/elastic/rendezvous/c10d_rendezvous_backend_test.py',
983+ 'test/distributed/elastic/rendezvous/dynamic_rendezvous_test.py',
984+ 'test/distributed/elastic/rendezvous/etcd_rendezvous_backend_test.py',
985+ 'test/distributed/elastic/rendezvous/etcd_rendezvous_test.py',
986+ 'test/distributed/elastic/rendezvous/etcd_server_test.py',
987+ 'test/distributed/elastic/rendezvous/rendezvous_backend_test.py',
988+ 'test/distributed/elastic/rendezvous/static_rendezvous_test.py',
989+ 'test/distributed/elastic/rendezvous/utils_test.py',
990+ 'test/distributed/elastic/timer/api_test.py',
991+ 'test/distributed/elastic/utils/data/cycling_iterator_test.py',
992+ 'test/distributed/launcher/api_test.py',
993+ 'test/distributed/launcher/bin/test_script.py',
994+ 'test/distributed/launcher/bin/test_script_init_method.py',
995+ 'test/distributed/launcher/bin/test_script_is_torchelastic_launched.py',
996+ 'test/distributed/launcher/bin/test_script_local_rank.py',
997+ 'test/distributed/launcher/launch_test.py',
998+ 'test/distributed/launcher/run_test.py',
999+ 'test/distributed/optim/test_apply_optimizer_in_backward.py',
1000+ 'test/distributed/optim/test_named_optimizer.py',
1001+ 'test/distributed/test_c10d_spawn.py',
1002+ 'test/distributed/test_collective_utils.py',
1003+ 'test/distributions/test_distributions.py',
1004+ 'test/inductor/test_aot_inductor_utils.py',
1005+ 'test/lazy/test_bindings.py',
1006+ 'test/lazy/test_extract_compiled_graph.py',
1007+ 'test/lazy/test_meta_kernel.py',
1008+ 'test/nn/test_init.py',
1009+ 'test/onnx/model_defs/op_test.py',
1010+ 'test/onnx/test_models_quantized_onnxruntime.py',
1011+ 'test/onnx/test_onnxscript_no_runtime.py',
1012+ 'test/onnx_caffe2/test_caffe2_common.py',
1013+ 'test/optim/test_lrscheduler.py',
1014+ 'test/optim/test_optim.py',
1015+ 'test/optim/test_swa_utils.py',
1016+ 'test/run_test.py',
1017+ 'test/test_bundled_images.py',
1018+ 'test/test_cuda_expandable_segments.py',
1019+ 'test/test_hub.py',
1020+]
1021+command = [
1022+ 'uv',
1023+ 'run',
1024+ '--script',
1025+ 'tools/linter/adapters/test_has_main_linter.py',
1026+ '--',
1027+ '@{{PATHSFILE}}',
1028+]
1029+ 
1030+[[linter]]
1031+code = 'CALL_ONCE'
1032+include_patterns = [
1033+ 'c10/**',
1034+ 'aten/**',
1035+ 'torch/csrc/**',
1036+ 'torch/nativert/**',
1037+]
1038+exclude_patterns = [
1039+ 'c10/util/CallOnce.h',
1040+ '**/fb/**',
1041+]
1042+command = [
1043+ 'python3',
1044+ 'tools/linter/adapters/grep_linter.py',
1045+ '--pattern=std::call_once',
1046+ '--linter-name=CALL_ONCE',
1047+ '--error-name=invalid call_once',
1048+ '--replace-pattern=s/std::call_once/c10::call_once/',
1049+ """--error-description=\
1050+ Use of std::call_once is forbidden and should be replaced with c10::call_once\
1051+ """,
1052+ '--',
1053+ '@{{PATHSFILE}}'
1054+]
1055+ 
1056+[[linter]]
1057+code = 'CONTEXT_DECORATOR'
1058+include_patterns = [
1059+ 'torch/**',
1060+]
1061+command = [
1062+ 'python3',
1063+ 'tools/linter/adapters/grep_linter.py',
1064+ '--pattern=@.*(dynamo_timed|preserve_rng_state|clear_frame|with_fresh_cache_if_config|use_lazy_graph_module|_disable_current_modes)',
1065+ '--allowlist-pattern=clear_frames',
1066+ '--linter-name=CONTEXT_DECORATOR',
1067+ '--error-name=avoid context decorator',
1068+ """--error-description=\
1069+ Do not use context manager as decorator as it breaks cProfile traces. Use it as \
1070+ a context manager instead\
1071+ """,
1072+ '--',
1073+ '@{{PATHSFILE}}'
1074+]
1075+ 
1076+[[linter]]
1077+code = 'ONCE_FLAG'
1078+include_patterns = [
1079+ 'c10/**',
1080+ 'aten/**',
1081+ 'torch/csrc/**',
1082+ 'torch/nativert/**',
1083+]
1084+exclude_patterns = [
1085+ '**/fb/**',
1086+]
1087+command = [
1088+ 'python3',
1089+ 'tools/linter/adapters/grep_linter.py',
1090+ '--pattern=std::once_flag',
1091+ '--linter-name=ONCE_FLAG',
1092+ '--error-name=invalid once_flag',
1093+ '--replace-pattern=s/std::once_flag/c10::once_flag/',
1094+ """--error-description=\
1095+ Use of std::once_flag is forbidden and should be replaced with c10::once_flag\
1096+ """,
1097+ '--',
1098+ '@{{PATHSFILE}}'
1099+]
1100+ 
1101+[[linter]]
1102+code = 'WORKFLOWSYNC'
1103+include_patterns = [
1104+ '.github/workflows/*.yml',
1105+ '.github/workflows/*.yaml',
1106+]
1107+command = [
1108+ 'uv',
1109+ 'run',
1110+ '--script',
1111+ 'tools/linter/adapters/workflow_consistency_linter.py',
1112+ '--',
1113+ '@{{PATHSFILE}}'
1114+]
1115+ 
1116+[[linter]]
1117+code = 'NO_WORKFLOWS_ON_FORK'
1118+include_patterns = [
1119+ '.github/**/*.yml',
1120+ '.github/**/*.yaml',
1121+]
1122+exclude_patterns = [
1123+ '**/fb/**',
1124+]
1125+command = [
1126+ 'uv',
1127+ 'run',
1128+ '--script',
1129+ 'tools/linter/adapters/no_workflows_on_fork.py',
1130+ '--',
1131+ '@{{PATHSFILE}}',
1132+]
1133+ 
1134+[[linter]]
1135+code = 'CODESPELL'
1136+command = [
1137+ 'uv',
1138+ 'run',
1139+ '--script',
1140+ 'tools/linter/adapters/codespell_linter.py',
1141+ '--',
1142+ '@{{PATHSFILE}}'
1143+]
1144+include_patterns = [
1145+ '**',
1146+]
1147+exclude_patterns = [
1148+ # We don't care too much about files in this directory, don't enforce
1149+ # spelling on them
1150+ 'caffe2/**',
1151+ 'fb/**',
1152+ '**/fb/**',
1153+ 'third_party/**',
1154+ 'test/dynamo/cpython/**',
1155+ 'torch/_vendor/**',
1156+ 'torch/_inductor/fx_passes/serialized_patterns/**',
1157+ 'torch/_inductor/autoheuristic/artifacts/**',
1158+ 'torch/_inductor/kernel/vendored_templates/cutedsl/kernels/**',
1159+ 'torch/_inductor/kernel/vendored_templates/cutedsl/dense_blockscaled_gemm_persistent.py',
1160+ 'torch/utils/model_dump/preact.mjs',
1161+]
1162+is_formatter = true
1163+ 
1164+# usort + ruff-format
1165+[[linter]]
1166+code = 'PYFMT'
1167+include_patterns = [
1168+ '**/*.py',
1169+ '**/*.pyi',
1170+]
1171+command = [
1172+ 'uv',
1173+ 'run',
1174+ '--script',
1175+ 'tools/linter/adapters/pyfmt_linter.py',
1176+ '--',
1177+ '@{{PATHSFILE}}'
1178+]
1179+exclude_patterns = [
1180+ 'tools/gen_vulkan_spv.py',
1181+ # We don't care too much about files in this directory, don't enforce
1182+ # formatting on them
1183+ 'caffe2/**/*.py',
1184+ 'caffe2/**/*.pyi',
1185+ 'fb/**',
1186+ '**/fb/**',
1187+ 'test/dynamo/cpython/**',
1188+ 'third_party/**/*.py',
1189+ 'third_party/**/*.pyi',
1190+ 'torch/_vendor/**',
1191+ 'torch/_inductor/fx_passes/serialized_patterns/**',
1192+ 'torch/_inductor/autoheuristic/artifacts/**',
1193+ # Needs Python 3.12+
1194+ 'torch/testing/_internal/py312_intrinsics.py',
1195+ # These files are all grandfathered in, feel free to remove from this list
1196+ # as necessary
1197+ 'test/quantization/__init__.py',
1198+ 'test/quantization/core/__init__.py',
1199+ 'test/quantization/core/experimental/apot_fx_graph_mode_ptq.py',
1200+ 'test/quantization/core/experimental/apot_fx_graph_mode_qat.py',
1201+ 'test/quantization/core/experimental/quantization_util.py',
1202+ 'test/quantization/core/experimental/test_bits.py',
1203+ 'test/quantization/core/experimental/test_fake_quantize.py',
1204+ 'test/quantization/core/experimental/test_linear.py',
1205+ 'test/quantization/core/experimental/test_nonuniform_observer.py',
1206+ 'test/quantization/core/experimental/test_quantized_tensor.py',
1207+ 'test/quantization/core/experimental/test_quantizer.py',
1208+ 'test/quantization/core/test_backend_config.py',
1209+ 'test/quantization/core/test_docs.py',
1210+ 'test/quantization/core/test_quantized_functional.py',
1211+ 'test/quantization/core/test_quantized_module.py',
1212+ 'test/quantization/core/test_quantized_op.py',
1213+ 'test/quantization/core/test_quantized_tensor.py',
1214+ 'test/quantization/core/test_top_level_apis.py',
1215+ 'test/quantization/core/test_utils.py',
1216+ 'test/quantization/core/test_workflow_module.py',
1217+ 'test/quantization/core/test_workflow_ops.py',
1218+ 'test/quantization/fx/__init__.py',
1219+ 'test/quantization/fx/test_equalize_fx.py',
1220+ 'test/quantization/fx/test_model_report_fx.py',
1221+ 'test/quantization/fx/test_numeric_suite_fx.py',
1222+ 'test/quantization/fx/test_quantize_fx.py',
1223+ 'test/quantization/fx/test_subgraph_rewriter.py',
1224+ 'test/test_function_schema.py',
1225+ 'test/test_functional_autograd_benchmark.py',
1226+ 'test/test_functional_optim.py',
1227+ 'test/test_functionalization_of_rng_ops.py',
1228+ 'test/test_datapipe.py',
1229+ 'test/test_futures.py',
1230+ 'test/test_fx.py',
1231+ 'test/test_fx_experimental.py',
1232+ 'test/test_fx_passes.py',
1233+ 'test/test_fx_reinplace_pass.py',
1234+ 'test/test_import_stats.py',
1235+ 'test/test_itt.py',
1236+ 'test/test_jit.py',
1237+ 'test/test_jit_autocast.py',
1238+ 'test/test_jit_cuda_fuser.py',
1239+ 'test/test_jit_disabled.py',
1240+ 'test/test_jit_fuser.py',
1241+ 'test/test_jit_fuser_legacy.py',
1242+ 'test/test_jit_legacy.py',
1243+ 'test/test_jit_llga_fuser.py',
1244+ 'test/test_jit_profiling.py',
1245+ 'test/test_jit_simple.py',
1246+ 'test/test_jit_string.py',
1247+ 'test/test_jiterator.py',
1248+ 'test/test_kernel_launch_checks.py',
1249+ 'test/test_linalg.py',
1250+ 'test/test_masked.py',
1251+ 'test/test_maskedtensor.py',
1252+ 'test/test_matmul_cuda.py',
1253+ 'test/test_scaled_matmul_cuda.py',
1254+ 'test/test_meta.py',
1255+ 'test/test_metal.py',
1256+ 'test/test_mkl_verbose.py',
1257+ 'test/test_mkldnn.py',
1258+ 'test/test_mkldnn_fusion.py',
1259+ 'test/test_mkldnn_verbose.py',
1260+ 'test/test_mobile_optimizer.py',
1261+ 'test/test_model_dump.py',
1262+ 'test/test_modules.py',
1263+ 'test/test_monitor.py',
1264+ 'test/test_mps.py',
1265+ 'test/test_multiprocessing_spawn.py',
1266+ 'test/test_namedtensor.py',
1267+ 'test/test_namedtuple_return_api.py',
1268+ 'test/test_native_functions.py',
1269+ 'test/test_native_mha.py',
1270+ 'test/test_nn.py',
1271+ 'test/test_out_dtype_op.py',
1272+ 'test/test_overrides.py',
1273+ 'test/test_prims.py',
1274+ 'test/test_proxy_tensor.py',
1275+ 'test/test_pruning_op.py',
1276+ 'test/test_quantization.py',
1277+ 'test/test_reductions.py',
1278+ 'test/test_scatter_gather_ops.py',
1279+ 'test/test_schema_check.py',
1280+ 'test/test_segment_reductions.py',
1281+ 'test/test_serialization.py',
1282+ 'test/test_set_default_mobile_cpu_allocator.py',
1283+ 'test/test_sparse.py',
1284+ 'test/test_sparse_csr.py',
1285+ 'test/test_sparse_semi_structured.py',
1286+ 'test/test_spectral_ops.py',
1287+ 'test/test_stateless.py',
1288+ 'test/test_static_runtime.py',
1289+ 'test/test_subclass.py',
1290+ 'test/test_sympy_utils.py',
1291+ 'test/test_tensor_creation_ops.py',
1292+ 'test/test_tensorboard.py',
1293+ 'test/test_tensorexpr.py',
1294+ 'test/test_tensorexpr_pybind.py',
1295+ 'test/test_testing.py',
1296+ 'test/test_torch.py',
1297+ 'test/test_transformers.py',
1298+ 'test/test_type_promotion.py',
1299+ 'test/test_unary_ufuncs.py',
1300+ 'test/test_vulkan.py',
1301+ 'torch/_awaits/__init__.py',
1302+ 'torch/_export/__init__.py',
1303+ 'torch/_export/constraints.py',
1304+ 'torch/_export/db/__init__.py',
1305+ 'torch/_export/db/case.py',
1306+ 'torch/_export/db/examples/__init__.py',
1307+ 'torch/_export/db/examples/assume_constant_result.py',
1308+ 'torch/_export/db/examples/autograd_function.py',
1309+ 'torch/_export/db/examples/class_method.py',
1310+ 'torch/_export/db/examples/cond_branch_class_method.py',
1311+ 'torch/_export/db/examples/cond_branch_nested_function.py',
1312+ 'torch/_export/db/examples/cond_branch_nonlocal_variables.py',
1313+ 'torch/_export/db/examples/cond_closed_over_variable.py',
1314+ 'torch/_export/db/examples/cond_operands.py',
1315+ 'torch/_export/db/examples/cond_predicate.py',
1316+ 'torch/_export/db/examples/decorator.py',
1317+ 'torch/_export/db/examples/dictionary.py',
1318+ 'torch/_export/db/examples/dynamic_shape_assert.py',
1319+ 'torch/_export/db/examples/dynamic_shape_constructor.py',
1320+ 'torch/_export/db/examples/dynamic_shape_if_guard.py',
1321+ 'torch/_export/db/examples/dynamic_shape_map.py',
1322+ 'torch/_export/db/examples/dynamic_shape_round.py',
1323+ 'torch/_export/db/examples/dynamic_shape_slicing.py',
1324+ 'torch/_export/db/examples/dynamic_shape_view.py',
1325+ 'torch/_export/db/examples/fn_with_kwargs.py',
1326+ 'torch/_export/db/examples/list_contains.py',
1327+ 'torch/_export/db/examples/list_unpack.py',
1328+ 'torch/_export/db/examples/nested_function.py',
1329+ 'torch/_export/db/examples/null_context_manager.py',
1330+ 'torch/_export/db/examples/pytree_flatten.py',
1331+ 'torch/_export/db/examples/scalar_output.py',
1332+ 'torch/_export/db/examples/specialized_attribute.py',
1333+ 'torch/_export/db/examples/static_for_loop.py',
1334+ 'torch/_export/db/examples/static_if.py',
1335+ 'torch/_export/db/examples/tensor_setattr.py',
1336+ 'torch/_export/db/examples/type_reflection_method.py',
1337+ 'torch/_export/db/gen_example.py',
1338+ 'torch/_export/db/logging.py',
1339+ 'torch/testing/_internal/__init__.py',
1340+ 'torch/testing/_internal/autocast_test_lists.py',
1341+ 'torch/testing/_internal/autograd_function_db.py',
1342+ 'torch/testing/_internal/check_kernel_launches.py',
1343+ 'torch/testing/_internal/codegen/__init__.py',
1344+ 'torch/testing/_internal/codegen/random_topo_test.py',
1345+ 'torch/testing/_internal/common_cuda.py',
1346+ 'torch/testing/_internal/common_jit.py',
1347+ 'torch/testing/_internal/common_methods_invocations.py',
1348+ 'torch/testing/_internal/common_modules.py',
1349+ 'torch/testing/_internal/common_nn.py',
1350+ 'torch/testing/_internal/common_pruning.py',
1351+ 'torch/testing/_internal/common_quantization.py',
1352+ 'torch/testing/_internal/common_quantized.py',
1353+ 'torch/testing/_internal/common_subclass.py',
1354+ 'torch/testing/_internal/common_utils.py',
1355+ 'torch/testing/_internal/composite_compliance.py',
1356+ 'torch/testing/_internal/hop_db.py',
1357+ 'torch/testing/_internal/custom_op_db.py',
1358+ 'torch/testing/_internal/data/__init__.py',
1359+ 'torch/testing/_internal/data/network1.py',
1360+ 'torch/testing/_internal/data/network2.py',
1361+ 'torch/testing/_internal/dist_utils.py',
1362+ 'torch/testing/_internal/generated/__init__.py',
1363+ 'torch/testing/_internal/hypothesis_utils.py',
1364+ 'torch/testing/_internal/inductor_utils.py',
1365+ 'torch/testing/_internal/jit_metaprogramming_utils.py',
1366+ 'torch/testing/_internal/jit_utils.py',
1367+ 'torch/testing/_internal/logging_tensor.py',
1368+ 'torch/testing/_internal/logging_utils.py',
1369+ 'torch/testing/_internal/optests/__init__.py',
1370+ 'torch/testing/_internal/optests/aot_autograd.py',
1371+ 'torch/testing/_internal/optests/compile_check.py',
1372+ 'torch/testing/_internal/optests/fake_tensor.py',
1373+ 'torch/testing/_internal/optests/make_fx.py',
1374+ 'torch/testing/_internal/quantization_torch_package_models.py',
1375+ 'torch/testing/_internal/test_module/__init__.py',
1376+ 'torch/testing/_internal/test_module/future_div.py',
1377+ 'torch/testing/_internal/test_module/no_future_div.py',
1378+ 'torch/utils/benchmark/__init__.py',
1379+ 'torch/utils/benchmark/examples/__init__.py',
1380+ 'torch/utils/benchmark/examples/compare.py',
1381+ 'torch/utils/benchmark/examples/fuzzer.py',
1382+ 'torch/utils/benchmark/examples/op_benchmark.py',
1383+ 'torch/utils/benchmark/examples/simple_timeit.py',
1384+ 'torch/utils/benchmark/examples/sparse/compare.py',
1385+ 'torch/utils/benchmark/examples/sparse/fuzzer.py',
1386+ 'torch/utils/benchmark/examples/sparse/op_benchmark.py',
1387+ 'torch/utils/benchmark/examples/spectral_ops_fuzz_test.py',
1388+ 'torch/utils/benchmark/op_fuzzers/__init__.py',
1389+ 'torch/utils/benchmark/op_fuzzers/binary.py',
1390+ 'torch/utils/benchmark/op_fuzzers/sparse_binary.py',
1391+ 'torch/utils/benchmark/op_fuzzers/sparse_unary.py',
1392+ 'torch/utils/benchmark/op_fuzzers/spectral.py',
1393+ 'torch/utils/benchmark/op_fuzzers/unary.py',
1394+ 'torch/utils/benchmark/utils/__init__.py',
1395+ 'torch/utils/benchmark/utils/_stubs.py',
1396+ 'torch/utils/benchmark/utils/common.py',
1397+ 'torch/utils/benchmark/utils/compare.py',
1398+ 'torch/utils/benchmark/utils/compile.py',
1399+ 'torch/utils/benchmark/utils/cpp_jit.py',
1400+ 'torch/utils/benchmark/utils/fuzzer.py',
1401+ 'torch/utils/benchmark/utils/sparse_fuzzer.py',
1402+ 'torch/utils/benchmark/utils/timer.py',
1403+ 'torch/utils/benchmark/utils/valgrind_wrapper/__init__.py',
1404+ 'torch/utils/benchmark/utils/valgrind_wrapper/timer_interface.py',
1405+ 'torch/utils/bundled_inputs.py',
1406+ 'torch/utils/checkpoint.py',
1407+ 'torch/utils/collect_env.py',
1408+ 'torch/utils/cpp_backtrace.py',
1409+ 'torch/utils/cpp_extension.py',
1410+ 'torch/utils/dlpack.py',
1411+ 'torch/utils/file_baton.py',
1412+ 'torch/utils/flop_counter.py',
1413+ 'torch/utils/hipify/__init__.py',
1414+ 'torch/utils/hipify/constants.py',
1415+ 'torch/utils/hipify/cuda_to_hip_mappings.py',
1416+ 'torch/utils/hipify/hipify_python.py',
1417+ 'torch/utils/hipify/version.py',
1418+ 'torch/utils/hooks.py',
1419+ 'torch/utils/jit/__init__.py',
1420+ 'torch/utils/jit/log_extract.py',
1421+ 'torch/utils/mkldnn.py',
1422+ 'torch/utils/mobile_optimizer.py',
1423+ 'torch/utils/model_dump/__init__.py',
1424+ 'torch/utils/model_dump/__main__.py',
1425+ 'torch/utils/model_zoo.py',
1426+ 'torch/utils/show_pickle.py',
1427+ 'torch/utils/tensorboard/__init__.py',
1428+ 'torch/utils/tensorboard/_caffe2_graph.py',
1429+ 'torch/utils/tensorboard/_convert_np.py',
1430+ 'torch/utils/tensorboard/_embedding.py',
1431+ 'torch/utils/tensorboard/_onnx_graph.py',
1432+ 'torch/utils/tensorboard/_proto_graph.py',
1433+ 'torch/utils/tensorboard/_pytorch_graph.py',
1434+ 'torch/utils/tensorboard/_utils.py',
1435+ 'torch/utils/tensorboard/summary.py',
1436+ 'torch/utils/tensorboard/writer.py',
1437+ 'torch/utils/throughput_benchmark.py',
1438+ 'torch/utils/viz/__init__.py',
1439+ 'torch/utils/viz/_cycles.py',
1440+]
1441+is_formatter = true
1442+ 
1443+[[linter]]
1444+code = 'PYPROJECT'
1445+command = [
1446+ 'uv',
1447+ 'run',
1448+ '--script',
1449+ 'tools/linter/adapters/pyproject_linter.py',
1450+ '--',
1451+ '@{{PATHSFILE}}'
1452+]
1453+include_patterns = [
1454+ "**/pyproject.toml",
1455+]
1456+ 
1457+[[linter]]
1458+code = 'CMAKE_MINIMUM_REQUIRED'
1459+command = [
1460+ 'uv',
1461+ 'run',
1462+ '--script',
1463+ 'tools/linter/adapters/cmake_minimum_required_linter.py',
1464+ '--',
1465+ '@{{PATHSFILE}}'
1466+]
1467+include_patterns = [
1468+ "**/pyproject.toml",
1469+ "**/CMakeLists.txt",
1470+ "**/CMakeLists.txt.in",
1471+ "**/*.cmake",
1472+ "**/*.cmake.in",
1473+ "**/*requirements*.txt",
1474+ "**/*requirements*.in",
1475+]
1476+ 
1477+[[linter]]
1478+code = 'COPYRIGHT'
1479+include_patterns = ['**']
1480+exclude_patterns = [
1481+ '.lintrunner.toml',
1482+ 'fb/**',
1483+ '**/fb/**',
1484+]
1485+command = [
1486+ 'python3',
1487+ 'tools/linter/adapters/grep_linter.py',
1488+ '--pattern=Confidential and proprietary',
1489+ '--linter-name=COPYRIGHT',
1490+ '--error-name=Confidential Code',
1491+ """--error-description=\
1492+ Proprietary and confidential source code\
1493+ should not be contributed to PyTorch codebase\
1494+ """,
1495+ '--',
1496+ '@{{PATHSFILE}}'
1497+]
1498+ 
1499+[[linter]]
1500+code = 'BAZEL_LINTER'
1501+include_patterns = ['WORKSPACE']
1502+command = [
1503+ 'python3',
1504+ 'tools/linter/adapters/bazel_linter.py',
1505+ '--binary=.lintbin/bazel',
1506+ '--',
1507+ '@{{PATHSFILE}}'
1508+]
1509+init_command = [
1510+ 'python3',
1511+ 'tools/linter/adapters/s3_init.py',
1512+ '--config-json=tools/linter/adapters/s3_init_config.json',
1513+ '--linter=bazel',
1514+ '--dry-run={{DRYRUN}}',
1515+ '--output-dir=.lintbin',
1516+ '--output-name=bazel',
1517+]
1518+is_formatter = true
1519+ 
1520+[[linter]]
1521+code = 'LINTRUNNER_VERSION'
1522+include_patterns = ['**']
1523+exclude_patterns = [
1524+ 'fb/**',
1525+ '**/fb/**',
1526+]
1527+command = [
1528+ 'python3',
1529+ 'tools/linter/adapters/lintrunner_version_linter.py'
1530+]
1531+ 
1532+[[linter]]
1533+code = 'RUFF'
1534+include_patterns = [
1535+ '**/*.py',
1536+ '**/*.pyi',
1537+ '**/*.ipynb',
1538+ 'pyproject.toml',
1539+]
1540+exclude_patterns = [
1541+ 'caffe2/**',
1542+ 'functorch/docs/**',
1543+ 'torch/_inductor/fx_passes/serialized_patterns/**',
1544+ 'torch/_inductor/autoheuristic/artifacts/**',
1545+ 'torch/_inductor/kernel/vendored_templates/cutedsl/kernels/**',
1546+ 'torch/_inductor/kernel/vendored_templates/cutedsl/dense_blockscaled_gemm_persistent.py',
1547+ 'test/dynamo/cpython/**',
1548+ 'test/test_torchfuzz_repros.py',
1549+ 'scripts/**',
1550+ 'third_party/**',
1551+ 'fb/**',
1552+ '**/fb/**',
1553+]
1554+command = [
1555+ 'uv',
1556+ 'run',
1557+ '--script',
1558+ 'tools/linter/adapters/ruff_linter.py',
1559+ '--config=pyproject.toml',
1560+ '--show-disable',
1561+ '--',
1562+ '@{{PATHSFILE}}'
1563+]
1564+is_formatter = true
1565+ 
1566+# This linter prevents merge conflicts in csv files in pytorch by enforcing
1567+# three lines of whitespace between entries such that unless people are modifying
1568+# the same line, merge conflicts should not arise in git or hg
1569+[[linter]]
1570+code = 'MERGE_CONFLICTLESS_CSV'
1571+include_patterns = [
1572+ 'benchmarks/dynamo/ci_expected_accuracy/*.csv',
1573+ 'benchmarks/dynamo/pr_time_benchmarks/expected_results.csv',
1574+]
1575+command = [
1576+ 'python3',
1577+ 'tools/linter/adapters/no_merge_conflict_csv_linter.py',
1578+ '--',
1579+ '@{{PATHSFILE}}'
1580+]
1581+is_formatter = true
1582+ 
1583+ 
1584+[[linter]]
1585+code = 'META_NO_CREATE_UNBACKED'
1586+include_patterns = [
1587+ "torch/_meta_registrations.py"
1588+]
1589+command = [
1590+ 'python3',
1591+ 'tools/linter/adapters/grep_linter.py',
1592+ '--pattern=create_unbacked',
1593+ '--linter-name=META_NO_CREATE_UNBACKED',
1594+ '--error-name=no create_unbacked in meta registrations',
1595+ """--error-description=\
1596+ Data-dependent operators should have their meta \
1597+ registration in torch/_subclasses/fake_impls.py, \
1598+ not torch/_meta_registrations.py
1599+ """,
1600+ '--',
1601+ '@{{PATHSFILE}}'
1602+]
1603+ 
1604+[[linter]]
1605+code = 'ATEN_CPU_GPU_AGNOSTIC'
1606+include_patterns = [
1607+ # aten source
1608+ "aten/src/ATen/*.cpp",
1609+ "aten/src/ATen/cpu/*.cpp",
1610+ "aten/src/ATen/functorch/**/*.cpp",
1611+ "aten/src/ATen/nnapi/*.cpp",
1612+ "aten/src/ATen/quantized/*.cpp",
1613+ "aten/src/ATen/vulkan/*.cpp",
1614+ "aten/src/ATen/metal/*.cpp",
1615+ "aten/src/ATen/detail/CPUGuardImpl.cpp",
1616+ "aten/src/ATen/detail/MetaGuardImpl.cpp",
1617+ # aten native source
1618+ "aten/src/ATen/native/cpu/*.cpp",
1619+ "aten/src/ATen/native/ao_sparse/cpu/kernels/*.cpp",
1620+ "aten/src/ATen/native/ao_sparse/quantized/cpu/kernels/*.cpp",
1621+ "aten/src/ATen/native/quantized/cpu/kernels/*.cpp",
1622+ "aten/src/ATen/native/*.cpp",
1623+ "aten/src/ATen/native/cpu/**/*.cpp",
1624+ "aten/src/ATen/native/ao_sparse/*.cpp",
1625+ "aten/src/ATen/native/ao_sparse/**/*.cpp",
1626+ "aten/src/ATen/native/ao_sparse/quantized/*.cpp",
1627+ "aten/src/ATen/native/ao_sparse/quantized/**/*.cpp",
1628+ "aten/src/ATen/native/nested/*.cpp",
1629+ "aten/src/ATen/native/quantized/*.cpp",
1630+ "aten/src/ATen/native/quantized/**/*.cpp",
1631+ "aten/src/ATen/native/sparse/*.cpp",
1632+ "aten/src/ATen/native/transformers/*.cpp",
1633+ "aten/src/ATen/native/utils/*.cpp",
1634+ "aten/src/ATen/native/xnnpack/*.cpp",
1635+ "aten/src/ATen/native/metal/MetalPrepackOpRegister.cpp",
1636+ # aten headers
1637+ "aten/src/ATen/*.h",
1638+ "aten/src/ATen/functorch/**/*.h",
1639+ "aten/src/ATen/ops/*.h",
1640+ "aten/src/ATen/cpu/**/*.h",
1641+ "aten/src/ATen/nnapi/*.h",
1642+ "aten/src/ATen/quantized/*.h",
1643+ "aten/src/ATen/vulkan/*.h",
1644+ "aten/src/ATen/metal/*.h",
1645+ "aten/src/ATen/mps/*.h",
1646+ # aten native headers
1647+ "aten/src/ATen/native/*.h",
1648+ "aten/src/ATen/native/cpu/**/*.h",
1649+ "aten/src/ATen/native/nested/*.h",
1650+ "aten/src/ATen/native/sparse/*.h",
1651+ "aten/src/ATen/native/ao_sparse/*.h",
1652+ "aten/src/ATen/native/ao_sparse/cpu/*.h",
1653+ "aten/src/ATen/native/ao_sparse/quantized/*.h",
1654+ "aten/src/ATen/native/ao_sparse/quantized/cpu/*.h",
1655+ "aten/src/ATen/native/quantized/*.h",
1656+ "aten/src/ATen/native/quantized/cpu/*.h",
1657+ "aten/src/ATen/native/transformers/*.h",
1658+ "aten/src/ATen/native/quantized/cpu/qnnpack/include/*.h",
1659+ "aten/src/ATen/native/utils/*.h",
1660+ "aten/src/ATen/native/vulkan/ops/*.h",
1661+ "aten/src/ATen/native/xnnpack/*.h",
1662+ "aten/src/ATen/native/metal/MetalPrepackOpContext.h",
1663+ "aten/src/ATen/native/mps/Copy.h",
1664+ "aten/src/ATen/native/mkldnn/**/*.h",
1665+]
1666+exclude_patterns = [
1667+ "aten/src/ATen/Context.h",
1668+ "aten/src/ATen/Context.cpp",
1669+ "aten/src/ATen/DLConvertor.cpp",
1670+ "aten/src/ATen/core/Array.h",
1671+ "aten/src/ATen/native/quantized/ConvUtils.h",
1672+ "aten/src/ATen/native/sparse/SparseBlasImpl.cpp", # triton implementation
1673+ "aten/src/ATen/native/transformers/attention.cpp",
1674+ "aten/src/ATen/native/**/cudnn/**", # cudnn is cuda specific
1675+]
1676+command = [
1677+ 'python3',
1678+ 'tools/linter/adapters/grep_linter.py',
1679+ '--pattern=(^#if.*USE_ROCM.*)|(^#if.*USE_CUDA.*)',
1680+ '--linter-name=ATEN_CPU',
1681+ '--error-name=aten-cpu should be gpu agnostic',
1682+ """--error-description=\
1683+ We strongly discourage the compile-time divergence \
1684+ on ATen-CPU code for different GPU code. This \
1685+ disallows sharing the same aten-cpu shared object \
1686+ between different GPU backends \
1687+ """,
1688+ '--',
1689+ '@{{PATHSFILE}}'
1690+]
1691+is_formatter = true
1692+ 
1693+# `set_linter` detects occurrences of built-in `set` in areas of Python code like
1694+# _inductor where the instability of iteration in `set` has proven a problem.
1695+ 
1696+[[linter]]
1697+code = 'SET_LINTER'
1698+command = [
1699+ 'python3',
1700+ 'tools/linter/adapters/set_linter.py',
1701+ '--lintrunner',
1702+ '--',
1703+ '@{{PATHSFILE}}'
1704+]
1705+include_patterns = [
1706+ "torch/_inductor/**/*.py",
1707+ "torch/_functorch/partitioners.py",
1708+]
1709+is_formatter = true
1710+ 
1711+# `docstring_linter` reports on long Python classes, methods, and functions
1712+# whose definitions have very small docstrings or none at all.
1713+#
1714+[[linter]]
1715+code = 'DOCSTRING_LINTER'
1716+command = [
1717+ 'python3',
1718+ 'tools/linter/adapters/docstring_linter.py',
1719+ '--lintrunner',
1720+ '--',
1721+ '@{{PATHSFILE}}'
1722+]
1723+include_patterns = [
1724+ 'torch/_inductor/**/*.py'
1725+]
1726+exclude_patterns = [
1727+ 'torch/_inductor/kernel/vendored_templates/cutedsl/kernels/**',
1728+ 'torch/_inductor/kernel/vendored_templates/cutedsl/dense_blockscaled_gemm_persistent.py',
1729+]
1730+is_formatter = false
1731+ 
1732+# `import_linter` reports on importing disallowed third party libraries.
1733+[[linter]]
1734+code = 'IMPORT_LINTER'
1735+command = [
1736+ 'python3',
1737+ 'tools/linter/adapters/import_linter.py',
1738+ '--',
1739+ '@{{PATHSFILE}}'
1740+]
1741+include_patterns = [
1742+ 'torch/_dynamo/**',
1743+]
1744+is_formatter = false
1745+ 
1746+[[linter]]
1747+code = 'TEST_DEVICE_BIAS'
1748+command = [
1749+ 'python3',
1750+ 'tools/linter/adapters/test_device_bias_linter.py',
1751+ '--',
1752+ '@{{PATHSFILE}}',
1753+]
1754+include_patterns = [
1755+ 'test/**/test_*.py',
1756+]
1757+exclude_patterns = [
1758+ # CPython tests
1759+ 'test/dynamo/cpython/**',
1760+]
1761+ 
1762+# 'header_only_linter' reports on properly testing header-only APIs.
1763+[[linter]]
1764+code = 'HEADER_ONLY_LINTER'
1765+command = [
1766+ 'python3',
1767+ 'tools/linter/adapters/header_only_linter.py',
1768+]
1769+include_patterns = [
1770+ 'torch/header_only_apis.txt',
1771+]
1772+is_formatter = false
1773+ 
1774+ 
1775+[[linter]]
1776+code = "GB_REGISTRY"
1777+include_patterns = ["torch/_dynamo/**/*.py"]
1778+command = [
1779+ "python3",
1780+ "tools/linter/adapters/gb_registry_linter.py",
1781+]
1782+ 
1783+[[linter]]
1784+code = 'STABLE_SHIM_VERSION'
1785+include_patterns = [
1786+ 'torch/csrc/stable/c/shim.h',
1787+ 'torch/csrc/inductor/aoti_torch/c/shim.h'
1788+]
1789+command = [
1790+ 'python3',
1791+ 'tools/linter/adapters/stable_shim_version_linter.py',
1792+ '--',
1793+ '@{{PATHSFILE}}'
1794+]
1795+ 
1796+[[linter]]
1797+code = 'STABLE_SHIM_USAGE'
1798+include_patterns = [
1799+ 'torch/csrc/stable/**/*.h',
1800+]
1801+command = [
1802+ 'python3',
1803+ 'tools/linter/adapters/stable_shim_usage_linter.py',
1804+ '--',
1805+ '@{{PATHSFILE}}'
1806+]
@@ -0,0 +1,65 @@
1+# This is the PyTorch mypy-strict.ini file (note: don't change this line! -
2+# test_run_mypy in test/test_type_hints.py uses this string)
3+ 
4+# Unlike mypy.ini, it enforces very strict typing rules. The intention is for
5+# this config file to be used to ENFORCE that people are using mypy on codegen
6+# files.
7+ 
8+[mypy]
9+python_version = 3.10
10+plugins = mypy_plugins/check_mypy_version.py, numpy.typing.mypy_plugin
11+ 
12+cache_dir = .mypy_cache/strict
13+allow_redefinition = True
14+strict_optional = True
15+show_error_codes = True
16+show_column_numbers = True
17+warn_no_return = True
18+disallow_any_unimported = True
19+ 
20+strict = True
21+implicit_reexport = False
22+ 
23+# do not re-enable this:
24+# https://github.com/pytorch/pytorch/pull/60006#issuecomment-866130657
25+warn_unused_ignores = False
26+ 
27+files =
28+ .github,
29+ benchmarks/instruction_counts,
30+ tools,
31+ torch/profiler/_memory_profiler.py,
32+ torch/utils/_pytree.py,
33+ torch/utils/_cxx_pytree.py,
34+ torch/utils/benchmark/utils/common.py,
35+ torch/utils/benchmark/utils/timer.py,
36+ torch/utils/benchmark/utils/valgrind_wrapper
37+ 
38+# Specifically enable imports of benchmark utils. As more of `torch` becomes
39+# strict compliant, those modules can be enabled as well.
40+[mypy-torch.utils.benchmark.utils.*]
41+follow_imports = normal
42+ 
43+# Don't follow imports as much of `torch` is not strict compliant.
44+[mypy-torch]
45+follow_imports = skip
46+ 
47+[mypy-torch.*]
48+follow_imports = skip
49+ 
50+# Missing stubs.
51+ 
52+[mypy-numpy]
53+ignore_missing_imports = True
54+ 
55+[mypy-sympy]
56+ignore_missing_imports = True
57+ 
58+[mypy-sympy.*]
59+ignore_missing_imports = True
60+ 
61+[mypy-mypy.*]
62+ignore_missing_imports = True
63+ 
64+[mypy-usort.*]
65+ignore_missing_imports = True
Amypy.ini+311-0
@@ -0,0 +1,311 @@
1+# This is the PyTorch mypy.ini file (note: don't change this line! -
2+# test_run_mypy in test/test_type_hints.py uses this string)
3+ 
4+[mypy]
5+plugins = mypy_plugins/check_mypy_version.py, mypy_plugins/sympy_mypy_plugin.py
6+ 
7+cache_dir = .mypy_cache/normal
8+allow_redefinition = True
9+warn_unused_configs = True
10+warn_redundant_casts = True
11+show_error_codes = True
12+show_column_numbers = True
13+check_untyped_defs = True
14+disallow_untyped_defs = True
15+disallow_untyped_decorators = True
16+follow_imports = normal
17+local_partial_types = True
18+enable_error_code = possibly-undefined
19+ 
20+# do not re-enable this:
21+# https://github.com/pytorch/pytorch/pull/60006#issuecomment-866130657
22+warn_unused_ignores = False
23+ 
24+#
25+# Note: test/ still has syntax errors so can't be added
26+#
27+# Typing tests is low priority, but enabling type checking on the
28+# untyped test functions (using `--check-untyped-defs`) is still
29+# high-value because it helps test the typing.
30+#
31+ 
32+files =
33+ torch,
34+ caffe2,
35+ test/test_bundled_images.py,
36+ test/test_bundled_inputs.py,
37+ test/test_complex.py,
38+ test/test_datapipe.py,
39+ test/test_futures.py,
40+ test/test_numpy_interop.py,
41+ test/test_torch.py,
42+ test/test_type_hints.py,
43+ test/test_type_info.py,
44+ test/test_utils.py
45+ 
46+#
47+# `exclude` is a regex, not a list of paths like `files` (sigh)
48+#
49+exclude = torch/include/|torch/csrc/|torch/distributed/elastic/agent/server/api.py|torch/testing/_internal|torch/distributed/fsdp/fully_sharded_data_parallel.py
50+ 
51+python_version = 3.11
52+ 
53+ 
54+#
55+# Extension modules without stubs.
56+#
57+ 
58+[mypy-torch.for_onnx.onnx]
59+ignore_missing_imports = True
60+ 
61+[mypy-torch.ao.quantization.experimental.apot_utils]
62+ignore_missing_imports = True
63+ 
64+[mypy-torch.ao.quantization.experimental.quantizer]
65+ignore_missing_imports = True
66+ 
67+[mypy-torch.ao.quantization.experimental.observer]
68+ignore_missing_imports = True
69+ 
70+[mypy-torch.ao.quantization.experimental.APoT_tensor]
71+ignore_missing_imports = True
72+ 
73+[mypy-torch.ao.quantization.experimental.fake_quantize_function]
74+ignore_missing_imports = True
75+ 
76+[mypy-torch.ao.quantization.experimental.fake_quantize]
77+ignore_missing_imports = True
78+ 
79+[mypy-torch.ao.quantization.pt2e._affine_quantization]
80+ignore_errors = True
81+ 
82+#
83+# Files with various errors. Mostly real errors, possibly some false
84+# positives as well.
85+#
86+ 
87+[mypy-test_torch]
88+check_untyped_defs = False
89+ 
90+# Excluded from mypy due to OpInfos being annoying to type
91+[mypy-torch.testing._internal.common_methods_invocations.*]
92+ignore_errors = True
93+ 
94+[mypy-torch.testing._internal.hypothesis_utils.*]
95+ignore_errors = True
96+ 
97+[mypy-torch.testing._internal.common_quantization.*]
98+ignore_errors = True
99+ 
100+[mypy-torch.testing._internal.generated.*]
101+ignore_errors = True
102+ 
103+[mypy-torch.testing._internal.distributed.*]
104+ignore_errors = True
105+ 
106+[mypy-torch.nn.modules.pooling]
107+ignore_errors = True
108+ 
109+[mypy-torch.nn.parallel._functions]
110+ignore_errors = True
111+ 
112+[mypy-torch._appdirs]
113+ignore_errors = True
114+ 
115+[mypy-torch.multiprocessing.pool]
116+ignore_errors = True
117+ 
118+[mypy-torch.overrides]
119+ignore_errors = True
120+ 
121+#
122+# Files with 'type: ignore' comments that are needed if checked with mypy-strict.ini
123+#
124+ 
125+[mypy-tools.render_junit]
126+warn_unused_ignores = False
127+ 
128+[mypy-tools.generate_torch_version]
129+warn_unused_ignores = False
130+ 
131+#
132+# Adding type annotations to caffe2 is probably not worth the effort
133+# only work on this if you have a specific reason for it, otherwise
134+# leave these ignores as they are.
135+#
136+ 
137+[mypy-caffe2.python.*]
138+ignore_errors = True
139+ 
140+[mypy-caffe2.proto.*]
141+ignore_errors = True
142+ 
143+[mypy-caffe2.distributed.store_ops_test_util]
144+ignore_errors = True
145+ 
146+[mypy-caffe2.experiments.*]
147+ignore_errors = True
148+ 
149+[mypy-caffe2.contrib.*]
150+ignore_errors = True
151+ 
152+[mypy-caffe2.quantization.server.*]
153+ignore_errors = True
154+ 
155+#
156+# Third party dependencies that don't have types.
157+#
158+ 
159+[mypy-triton.*]
160+ignore_missing_imports = True
161+ 
162+[mypy-tensorflow.*]
163+ignore_missing_imports = True
164+ 
165+[mypy-tensorboard.*]
166+ignore_missing_imports = True
167+ 
168+[mypy-matplotlib.*]
169+ignore_missing_imports = True
170+ 
171+[mypy-numpy.*]
172+ignore_missing_imports = True
173+ 
174+[mypy-sympy]
175+ignore_missing_imports = True
176+ 
177+[mypy-sympy.*]
178+ignore_missing_imports = True
179+ 
180+[mypy-hypothesis.*]
181+ignore_missing_imports = True
182+ 
183+[mypy-tqdm.*]
184+ignore_missing_imports = True
185+ 
186+[mypy-multiprocessing.*]
187+ignore_missing_imports = True
188+ 
189+[mypy-setuptools.*]
190+ignore_missing_imports = True
191+ 
192+[mypy-distutils.*]
193+ignore_missing_imports = True
194+ 
195+[mypy-nvd3.*]
196+ignore_missing_imports = True
197+ 
198+[mypy-future.utils]
199+ignore_missing_imports = True
200+ 
201+[mypy-past.builtins]
202+ignore_missing_imports = True
203+ 
204+[mypy-numba.*]
205+ignore_missing_imports = True
206+ 
207+[mypy-PIL.*]
208+ignore_missing_imports = True
209+ 
210+[mypy-moviepy.*]
211+ignore_missing_imports = True
212+ 
213+[mypy-cv2.*]
214+ignore_missing_imports = True
215+ 
216+[mypy-torchvision.*]
217+ignore_missing_imports = True
218+ 
219+[mypy-pycuda.*]
220+ignore_missing_imports = True
221+ 
222+[mypy-tensorrt.*]
223+ignore_missing_imports = True
224+ 
225+[mypy-tornado.*]
226+ignore_missing_imports = True
227+ 
228+[mypy-pydot.*]
229+ignore_missing_imports = True
230+ 
231+[mypy-networkx.*]
232+ignore_missing_imports = True
233+ 
234+[mypy-scipy.*]
235+ignore_missing_imports = True
236+ 
237+[mypy-IPython.*]
238+ignore_missing_imports = True
239+ 
240+[mypy-google.protobuf.textformat]
241+ignore_missing_imports = True
242+ 
243+[mypy-lmdb.*]
244+ignore_missing_imports = True
245+ 
246+[mypy-mpi4py.*]
247+ignore_missing_imports = True
248+ 
249+[mypy-skimage.*]
250+ignore_missing_imports = True
251+ 
252+[mypy-librosa.*]
253+ignore_missing_imports = True
254+ 
255+[mypy-mypy.*]
256+ignore_missing_imports = True
257+ 
258+[mypy-xml.*]
259+ignore_missing_imports = True
260+ 
261+[mypy-boto3.*]
262+ignore_missing_imports = True
263+ 
264+[mypy-dill.*]
265+ignore_missing_imports = True
266+ 
267+[mypy-usort.*]
268+ignore_missing_imports = True
269+ 
270+[mypy-torch._inductor.*]
271+disallow_any_generics = True
272+ 
273+[mypy-torch._dynamo.*]
274+disallow_any_generics = True
275+ 
276+[mypy-cutlass_library.*]
277+ignore_missing_imports = True
278+ 
279+[mypy-deeplearning.*]
280+ignore_missing_imports = True
281+ 
282+[mypy-einops.*]
283+ignore_missing_imports = True
284+ 
285+[mypy-libfb.*]
286+ignore_missing_imports = True
287+ 
288+[mypy-torch.*.fb.*]
289+ignore_missing_imports = True
290+ 
291+[mypy-torch.fb.*]
292+ignore_missing_imports = True
293+ 
294+[mypy-torch_xla.*]
295+ignore_missing_imports = True
296+ 
297+#
298+# Third party dependencies that are optional.
299+#
300+ 
301+[mypy-onnx.*]
302+ignore_missing_imports = True
303+ 
304+[mypy-onnxruntime.*]
305+ignore_missing_imports = True
306+ 
307+[mypy-onnxscript.*]
308+ignore_missing_imports = True
309+ 
310+[mypy-redis]
311+ignore_missing_imports = True
@@ -0,0 +1,280 @@
1+# Package ######################################################################
2+ 
3+[project]
4+name = "torch_npu"
5+dynamic = [
6+ "classifiers",
7+ "entry-points",
8+ "dependencies",
9+ "scripts",
10+ "version",
11+ "description",
12+ "readme",
13+ "license",
14+]
15+ 
16+# Linter tools #################################################################
17+ 
18+[tool.isort]
19+src_paths = ["caffe2", "torch", "torchgen", "functorch", "test"]
20+extra_standard_library = ["typing_extensions"]
21+skip_gitignore = true
22+skip_glob = ["third_party/*"]
23+atomic = true
24+profile = "black"
25+indent = 4
26+line_length = 88
27+lines_after_imports = 2
28+multi_line_output = 3
29+include_trailing_comma = true
30+combine_as_imports = true
31+ 
32+[tool.usort]
33+preserve_inline_comments = true
34+collapse_blank_lines_in_category = false
35+ 
36+[tool.usort.known]
37+first_party = ["caffe2", "torch", "torchgen", "functorch", "test"]
38+standard_library = ["typing_extensions"]
39+ 
40+[tool.ruff]
41+line-length = 88
42+src = ["caffe2", "torch", "torchgen", "functorch", "test"]
43+extend-exclude = ["third_party", "test/dynamo/cpython"]
44+ 
45+[tool.ruff.per-file-target-version]
46+"**/py312_intrinsics.py" = "py312"
47+ 
48+[tool.ruff.format]
49+docstring-code-format = true
50+quote-style = "double"
51+ 
52+[tool.ruff.lint]
53+# NOTE: Synchoronize the ignores with .flake8
54+external = [
55+ "B001",
56+ "B902",
57+ "B950",
58+ "E121",
59+ "E122",
60+ "E128",
61+ "E131",
62+ "E704",
63+ "E723",
64+ "F723",
65+ "F812",
66+ "P201",
67+ "P204",
68+ "T484",
69+ "TOR901",
70+]
71+ignore = [
72+ # these ignores are from flake8-bugbear; please fix!
73+ "B007", "B008", "B017",
74+ "B018", # Useless expression
75+ "B023",
76+ "B028", # No explicit `stacklevel` keyword argument found
77+ "E402",
78+ "C408", # C408 ignored because we like the dict keyword argument syntax
79+ "E501", # E501 is not flexible enough, we're using B950 instead
80+ "E741",
81+ "EXE001",
82+ "F405",
83+ "FURB122", # writelines
84+ # these ignores are from ruff NPY; please fix!
85+ "NPY002",
86+ # these ignores are from ruff PERF; please fix!
87+ "PERF203",
88+ "PERF401",
89+ # these ignores are from PYI; please fix!
90+ "PYI024",
91+ "PYI036",
92+ "PYI041",
93+ "PYI056",
94+ "SIM102", "SIM103", "SIM112", # flake8-simplify code styles
95+ "SIM105", # these ignores are from flake8-simplify. please fix or ignore with commented reason
96+ "SIM108", # SIM108 ignored because we prefer if-else-block instead of ternary expression
97+ "SIM110", # Checks for for loops that can be replaced with a builtin function, like any or all.
98+ "SIM114", # Combine `if` branches using logical `or` operator
99+ "SIM116", # Disable Use a dictionary instead of consecutive `if` statements
100+ "SIM117",
101+ "SIM300", # Yoda condition detected
102+ "TC006",
103+ # TODO: Remove Python-3.10 specific suppressions
104+ "B905",
105+]
106+select = [
107+ "B",
108+ "B904", # Re-raised error without specifying the cause via the from keyword
109+ "C4",
110+ "G",
111+ "E",
112+ "EXE",
113+ "F",
114+ "SIM",
115+ "W",
116+ # Not included in flake8
117+ "FURB",
118+ "LOG",
119+ "NPY",
120+ "PERF",
121+ "PGH004",
122+ "PIE",
123+ "PLC0131", # type bivariance
124+ "PLC0132", # type param mismatch
125+ "PLC1802", # len({expression}) used as condition without comparison
126+ "PLC0205", # string as __slots__
127+ "PLC3002", # unnecessary-direct-lambda-call
128+ "PLC0414", # Import alias does not rename original package
129+ "PLE",
130+ "PLR0133", # constant comparison
131+ "PLR0206", # property with params
132+ "PLR1722", # use sys exit
133+ "PLR1736", # unnecessary list index
134+ "PLW0127", # Self-assignment of variable
135+ "PLW0129", # assert on string literal
136+ "PLW0131", # named expr without context
137+ "PLW0133", # useless exception statement
138+ "PLW0245", # super without brackets
139+ "PLW0406", # import self
140+ "PLW0711", # binary op exception
141+ "PLW1501", # bad open mode
142+ "PLW1507", # shallow copy os.environ
143+ "PLW1509", # preexec_fn not safe with threads
144+ "PLW2101", # useless lock statement
145+ "PLW3301", # nested min max
146+ "PT006", # TODO: enable more PT rules
147+ "PT014", # duplicate parameterize case
148+ "PT022",
149+ "PT023",
150+ "PT024",
151+ "PT025",
152+ "PT026",
153+ "PYI",
154+ "Q003", # avoidable escaped quote
155+ "Q004", # unnecessary escaped quote
156+ "RSE",
157+ "RUF007", # pairwise over zip
158+ "RUF008", # mutable dataclass default
159+ "RUF013", # ban implicit optional
160+ "RUF015", # access first ele in constant time
161+ "RUF016", # type error non-integer index
162+ "RUF017",
163+ "RUF018", # no assignment in assert
164+ "RUF019", # unnecessary-key-check
165+ "RUF020", # never union
166+ "RUF024", # from keys mutable
167+ "RUF026", # default factory kwarg
168+ "RUF030", # No print statement in assert
169+ "RUF033", # default values __post_init__ dataclass
170+ "RUF041", # simplify nested Literal
171+ "RUF048", # properly parse `__version__`
172+ "RUF200", # validate pyproject.toml
173+ "S324", # for hashlib FIPS compliance
174+ "SLOT",
175+ "TC",
176+ "TRY002", # ban vanilla raise (todo fix NOQAs)
177+ "TRY203",
178+ "TRY401", # verbose-log-message
179+ "UP",
180+ "YTT",
181+ "S101",
182+]
183+ 
184+[tool.ruff.lint.per-file-ignores]
185+"__init__.py" = [
186+ "F401",
187+]
188+"*.pyi" = [
189+ "PYI011", # typed-argument-default-in-stub
190+ "PYI021", # docstring-in-stub
191+ "PYI053", # string-or-bytes-too-long
192+]
193+"functorch/docs/source/tutorials/**" = [
194+ "F401",
195+]
196+"test/export/**" = [
197+ "PGH004",
198+]
199+"test/typing/**" = [
200+ "PGH004"
201+]
202+"test/typing/reveal/**" = [
203+ "F821",
204+]
205+"test/torch_np/numpy_tests/**" = [
206+ "F821",
207+ "NPY201",
208+]
209+"test/dynamo/test_bytecode_utils.py" = [
210+ "F821",
211+]
212+"test/dynamo/test_debug_utils.py" = [
213+ "UP037",
214+]
215+"test/dynamo/test_misc.py" = [
216+ "PGH004",
217+]
218+"test/jit/**" = [
219+ "PLR0133", # tests require this for JIT
220+ "PYI",
221+ "RUF015",
222+ "UP", # We don't want to modify the jit test as they test specify syntax
223+]
224+"test/test_jit.py" = [
225+ "PLR0133", # tests require this for JIT
226+ "PYI",
227+ "RUF015",
228+ "UP", # We don't want to modify the jit test as they test specify syntax
229+]
230+"test/inductor/s429861_repro.py" = [
231+ "PGH004",
232+]
233+"test/inductor/test_torchinductor.py" = [
234+ "UP037",
235+]
236+# autogenerated #TODO figure out why file level noqa is ignored
237+"torch/_appdirs.py" = ["PGH004"]
238+"torch/jit/_shape_functions.py" = ["PGH004"]
239+"torch/_inductor/fx_passes/serialized_patterns/**" = ["F401", "F501"]
240+"torch/_inductor/autoheuristic/artifacts/**" = ["F401", "F501"]
241+"torch/_inductor/codegen/**" = [
242+ "PGH004"
243+]
244+"torchgen/api/types/__init__.py" = [
245+ "F401",
246+ "F403",
247+]
248+"torch/utils/collect_env.py" = [
249+ "UP", # collect_env.py needs to work with older versions of Python
250+]
251+"torch/_vendor/**" = [
252+ "UP", # No need to mess with _vendor
253+]
254+"tools/linter/**" = [
255+ "LOG015" # please fix
256+]
257+ 
258+# torch/ folders still needing S101 migration
259+"torch/_dynamo/**" = ["S101"]
260+"torch/_inductor/**" = ["S101"]
261+ 
262+[tool.codespell]
263+ignore-words = "tools/linter/dictionary.txt"
264+ 
265+[tool.spin]
266+package = 'torch'
267+ 
268+[tool.spin.commands]
269+"Build" = [
270+ ".spin/cmds.py:lint",
271+ ".spin/cmds.py:fixlint",
272+ ".spin/cmds.py:quicklint",
273+ ".spin/cmds.py:quickfix",
274+]
275+"Regenerate" = [
276+ ".spin/cmds.py:regenerate_version",
277+ ".spin/cmds.py:regenerate_type_stubs",
278+ ".spin/cmds.py:regenerate_clangtidy_files",
279+ ".spin/cmds.py:regenerate_github_workflows",
280+]
@@ -0,0 +1,160 @@
1+# A Pyrefly configuration for PyTorch
2+# Based on https://github.com/pytorch/pytorch/blob/main/mypy.ini
3+python-version = "3.12"
4+ 
5+project-includes = [
6+ "torch",
7+ "caffe2",
8+ "tools",
9+ "test/test_bundled_images.py",
10+ "test/test_bundled_inputs.py",
11+ "test/test_complex.py",
12+ "test/test_datapipe.py",
13+ "test/test_futures.py",
14+ "test/test_numpy_interop.py",
15+ # We exclude test_torch.py because it is full of errors, but most functions lack type signatures,
16+ # and mypy.ini specifies `check_untyped_defs = False` for this file.
17+ # If you check even the unannotated stuff mypy produces 322 errors.
18+ # "test/test_torch.py",
19+ "test/test_type_hints.py",
20+ "test/test_type_info.py",
21+ "test/test_utils.py",
22+]
23+project-excludes = [
24+ "torch/_inductor/runtime/triton_heuristics.py",
25+ "torch/_inductor/runtime/triton_helpers.py",
26+ "torch/_inductor/runtime/halide_helpers.py",
27+ "torch/utils/data/typing.ipynb",
28+ "torch/utils/data/dataframes_pipes.ipynb",
29+ "torch/utils/data/standard_pipes.ipynb",
30+ "torch/onnx/_internal/exporter/_torchlib/ops/nn.py",
31+ "torch/include/**",
32+ "torch/csrc/**",
33+ "torch/distributed/elastic/agent/server/api.py",
34+ "torch/testing/_internal/**",
35+ "torch/distributed/fsdp/fully_sharded_data_parallel.py",
36+ "torch/ao/quantization/pt2e/_affine_quantization.py",
37+ "torch/nn/modules/pooling.py",
38+ "torch/nn/parallel/_functions.py",
39+ "torch/_appdirs.py",
40+ "torch/multiprocessing/pool.py",
41+ "torch/overrides.py",
42+ "*/__pycache__/**",
43+ "*/.*",
44+ "torch/_inductor/kernel/vendored_templates/cutedsl/kernels/**",
45+ "torch/_inductor/kernel/vendored_templates/cutedsl/dense_blockscaled_gemm_persistent.py",
46+]
47+ignore-missing-imports = [
48+ # XPU memory symbols not present for builds without XPU support
49+ "torch._C._xpu_beginAllocateCurrentThreadToPool",
50+ "torch._C._xpu_endAllocateToPool",
51+ "torch._C._xpu_releasePool",
52+ "torch._C._xpu_XPUAllocator",
53+ "torch._C._XPUMemPool",
54+ "torch._C._StaticXpuLauncher",
55+ "torch._C._jit_tree_views.*",
56+ "torch.for_onnx.onnx.*",
57+ "torch.ao.quantization.experimental.apot_utils.*",
58+ "torch.ao.quantization.experimental.quantizer.*",
59+ "torch.ao.quantization.experimental.observer.*",
60+ "torch.ao.quantization.experimental.APoT_tensor.*",
61+ "torch.ao.quantization.experimental.fake_quantize_function.*",
62+ "torch.ao.quantization.experimental.fake_quantize.*",
63+ "triton.*",
64+ "tensorflow.*",
65+ "tensorboard.*",
66+ "matplotlib.*",
67+ "numpy.*",
68+ "sympy.*",
69+ "hypothesis.*",
70+ "tqdm.*",
71+ "multiprocessing.*",
72+ "setuptools.*",
73+ "distutils.*",
74+ "nvd3.*",
75+ "future.utils.*",
76+ "past.builtins.*",
77+ "numba.*",
78+ "nvMatmulHeuristics",
79+ "PIL.*",
80+ "moviepy.*",
81+ "cv2.*",
82+ "torchvision.*",
83+ "pycuda.*",
84+ "tensorrt.*",
85+ "tornado.*",
86+ "pydot.*",
87+ "networkx.*",
88+ "scipy.*",
89+ "IPython.*",
90+ "google.protobuf.textformat.*",
91+ "lmdb.*",
92+ "mpi4py.*",
93+ "skimage.*",
94+ "librosa.*",
95+ "mypy.*",
96+ "xml.*",
97+ "boto3.*",
98+ "dill.*",
99+ "usort.*",
100+ "cutlass.*",
101+ "cutlass_library.*",
102+ "cutlass_api.*",
103+ "deeplearning.*",
104+ "einops.*",
105+ "libfb.*",
106+ "torch.fb.*",
107+ "torch.*.fb.*",
108+ "torch_xla.*",
109+ "onnx.*",
110+ "onnxruntime.*",
111+ "onnxscript.*",
112+ "redis.*",
113+]
114+# By default, mypy does not check untyped definitions.
115+# However, mypy has a configuration called check_untyped_defs which is used
116+# to typecheck the interior of untyped functions.
117+untyped-def-behavior = "check-and-infer-return-any"
118+# In lots of places they define their attributes in `_init` or similar.
119+# https://github.com/pytorch/pytorch/blob/75f3e5a88df60caef27fd9c9df3fd51161378fcc/torch/fx/experimental/symbolic_shapes.py#L3632C1-L3633C1
120+errors.implicitly-defined-attribute = false
121+# In many methods that are overridden, parameters are renamed.
122+# We can come up with a codemod for this in the future
123+errors.bad-param-name-override = false
124+# Mypy doesn't require that imports are explicitly imported, so be compatible with that.
125+# Might be a good idea to turn this on in future.
126+errors.implicit-import = false
127+errors.deprecated = false # re-enable after we've fix import formatting
128+ 
129+permissive-ignores = true
130+replace-imports-with-any = ["!sympy.printing.*", "sympy.*", "onnxscript.onnx_opset.*", "networkx.*"]
131+search-path = ["tools/experimental"]
132+ 
133+# Dynamo sub-config - note, we experiment with stricter typing here
134+[[sub-config]]
135+matches = "torch/_dynamo/**"
136+[sub-config.errors]
137+implicit-import = false
138+implicit-any = true
139+# TODO: Turn on in later version
140+# unannotated-attribute=true
141+# unannotated-parameter=true
142+# unannotated-return=true
143+ 
144+[[sub-config]]
145+matches = "torch/_dispatch/**"
146+[sub-config.errors]
147+implicit-import = false
148+implicit-any = true
149+ 
150+[[sub-config]]
151+matches = "torch/_subclasses/**"
152+[sub-config.errors]
153+implicit-import = false
154+implicit-any = true
155+ 
156+[[sub-config]]
157+matches = "torch/_functorch/**"
158+[sub-config.errors]
159+implicit-import = false
160+implicit-any = true
@@ -0,0 +1,10 @@
1+# lintrunner adapters
2+ 
3+These files adapt our various linters to work with `lintrunner`.
4+ 
5+## Adding a new linter
6+1. init and linter
7+2. {{DRYRUN}} and {{PATHSFILE}}
8+3. never exit uncleanly
9+4. Communication protocol
10+5. Self-contained
@@ -0,0 +1,49 @@
1+from __future__ import annotations
2+ 
3+import token
4+from pathlib import Path
5+from typing import Any, TYPE_CHECKING
6+ 
7+ 
8+if TYPE_CHECKING:
9+ from collections.abc import Sequence
10+ from tokenize import TokenInfo
11+ 
12+ 
13+__all__ = [
14+ "Block",
15+ "FileLinter",
16+ "is_empty",
17+ # pyrefly: ignore [bad-dunder-all]
18+ "LineWithSets",
19+ "LintResult",
20+ "ParseError",
21+ "PythonFile",
22+ "ROOT",
23+]
24+ 
25+NO_TOKEN = -1
26+ 
27+# Python 3.12 and up have two new token types, FSTRING_START and FSTRING_END
28+_START_OF_LINE_TOKENS = token.DEDENT, token.INDENT, token.NEWLINE
29+_IGNORED_TOKENS = token.COMMENT, token.ENDMARKER, token.ENCODING, token.NL
30+_EMPTY_TOKENS = dict.fromkeys(_START_OF_LINE_TOKENS + _IGNORED_TOKENS)
31+ 
32+_LINTER = Path(__file__).absolute().parents[0]
33+ROOT = _LINTER.parents[3]
34+ 
35+ 
36+class ParseError(ValueError):
37+ def __init__(self, token: TokenInfo, *args: str) -> None:
38+ super().__init__(*args)
39+ self.token = token
40+ 
41+ 
42+def is_empty(t: TokenInfo) -> bool:
43+ return t.type in _EMPTY_TOKENS
44+ 
45+ 
46+from .block import Block
47+from .file_linter import FileLinter
48+from .messages import LintResult
49+from .python_file import PythonFile