@neralabs/rerail-pack-python 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +713 -6
  2. package/licenses/ruff/UPSTREAM.md +3 -3
  3. package/package.json +1 -1
  4. package/rules/bandit-b101-assert-used.json +2 -2
  5. package/rules/bandit-b102-exec-used.json +2 -2
  6. package/rules/bandit-b110-try-except-pass.json +1 -1
  7. package/rules/bandit-b112-try-except-continue.json +1 -1
  8. package/rules/bandit-b113-request-without-timeout.json +2 -2
  9. package/rules/bandit-b301-pickle.json +2 -2
  10. package/rules/bandit-b302-marshal.json +2 -2
  11. package/rules/bandit-b303-md5.json +1 -1
  12. package/rules/bandit-b305-cipher-modes.json +2 -2
  13. package/rules/bandit-b306-mktemp-q.json +2 -2
  14. package/rules/bandit-b307-eval.json +1 -1
  15. package/rules/bandit-b308-mark-safe.json +2 -2
  16. package/rules/bandit-b310-urllib-urlopen.json +1 -1
  17. package/rules/bandit-b311-random.json +1 -1
  18. package/rules/bandit-b312-telnetlib.json +1 -1
  19. package/rules/bandit-b313-xml-bad-celementtree.json +1 -1
  20. package/rules/bandit-b314-xml-bad-elementtree.json +1 -1
  21. package/rules/bandit-b315-xml-bad-expatreader.json +1 -1
  22. package/rules/bandit-b316-xml-bad-expatbuilder.json +1 -1
  23. package/rules/bandit-b317-xml-bad-sax.json +1 -1
  24. package/rules/bandit-b318-xml-bad-minidom.json +1 -1
  25. package/rules/bandit-b319-xml-bad-pulldom.json +1 -1
  26. package/rules/bandit-b321-ftplib.json +2 -2
  27. package/rules/bandit-b323-unverified-context.json +2 -2
  28. package/rules/bandit-b401-import-telnetlib.json +2 -2
  29. package/rules/bandit-b402-import-ftplib.json +2 -2
  30. package/rules/bandit-b405-import-xml-etree.json +1 -1
  31. package/rules/bandit-b407-import-xml-expat.json +1 -1
  32. package/rules/bandit-b408-import-xml-minidom.json +1 -1
  33. package/rules/bandit-b409-import-xml-pulldom.json +1 -1
  34. package/rules/bandit-b411-import-xmlrpclib.json +1 -1
  35. package/rules/bandit-b413-import-pycrypto.json +1 -1
  36. package/rules/bandit-b415-import-pyghmi.json +2 -2
  37. package/rules/bandit-b502-ssl-with-bad-version.json +2 -2
  38. package/rules/bandit-b505-weak-cryptographic-key.json +2 -2
  39. package/rules/bandit-b507-ssh-no-host-key-verification.json +2 -2
  40. package/rules/bandit-b606-start-process-with-no-shell.json +2 -2
  41. package/rules/bandit-b615-huggingface-unsafe-download.json +2 -2
  42. package/rules/ruff-async100-cancel-scope-no-checkpoint.json +2 -2
  43. package/rules/ruff-async105-trio-sync-call.json +1 -1
  44. package/rules/ruff-async115-async-zero-sleep.json +1 -1
  45. package/rules/ruff-async116-long-sleep-not-forever.json +1 -1
  46. package/rules/ruff-async210-blocking-http-call-in-async-function.json +3 -3
  47. package/rules/ruff-async221-run-process-in-async-function.json +1 -1
  48. package/rules/ruff-async222-wait-for-process-in-async-function.json +3 -3
  49. package/rules/ruff-async230-blocking-open-call-in-async-function.json +2 -2
  50. package/rules/ruff-async250-blocking-input-in-async-function.json +2 -2
  51. package/rules/ruff-async251-blocking-sleep-in-async-function.json +1 -1
  52. package/rules/ruff-b002-unary-prefix-increment-decrement.json +3 -3
  53. package/rules/ruff-b003-assignment-to-os-environ.json +2 -2
  54. package/rules/ruff-b004-unreliable-callable-check.json +1 -1
  55. package/rules/ruff-b005-strip-with-multi-characters.json +2 -2
  56. package/rules/ruff-b007-unused-loop-control-variable.json +1 -1
  57. package/rules/ruff-b009-get-attr-with-constant.json +1 -1
  58. package/rules/ruff-b010-set-attr-with-constant.json +2 -2
  59. package/rules/ruff-b011-assert-false.json +1 -1
  60. package/rules/ruff-b013-redundant-tuple-in-exception-handler.json +1 -1
  61. package/rules/ruff-b014-duplicate-handler-exception.json +1 -1
  62. package/rules/ruff-b016-raise-literal.json +1 -1
  63. package/rules/ruff-b020-loop-variable-overrides-iterator.json +1 -1
  64. package/rules/ruff-b021-f-string-docstring.json +1 -1
  65. package/rules/ruff-b022-useless-contextlib-suppress.json +1 -1
  66. package/rules/ruff-b023-function-uses-loop-variable.json +2 -2
  67. package/rules/ruff-b025-duplicate-try-block-exception.json +1 -1
  68. package/rules/ruff-b026-star-arg-unpacking-after-keyword-arg.json +1 -1
  69. package/rules/ruff-b028-no-explicit-stacklevel.json +2 -2
  70. package/rules/ruff-b029-except-with-empty-tuple.json +1 -1
  71. package/rules/ruff-b030-except-with-non-exception-classes.json +1 -1
  72. package/rules/ruff-b032-unintentional-type-annotation.json +1 -1
  73. package/rules/ruff-b033-duplicate-value.json +1 -1
  74. package/rules/ruff-b034-re-sub-positional-args.json +1 -1
  75. package/rules/ruff-b039-mutable-contextvar-default.json +2 -2
  76. package/rules/ruff-b904-raise-without-from-inside-except.json +2 -2
  77. package/rules/ruff-b905-zip-without-explicit-strict.json +3 -3
  78. package/rules/ruff-e711-none-comparison.json +190 -6
  79. package/rules/ruff-e721-type-comparison.json +1 -1
  80. package/rules/ruff-e722-bare-except.json +2 -2
  81. package/rules/ruff-e742-ambiguous-class-name.json +2 -2
  82. package/rules/ruff-e743-ambiguous-function-name.json +2 -2
  83. package/rules/ruff-f403-undefined-local-with-import-star.json +1 -1
  84. package/rules/ruff-f405-undefined-local-with-import-star-usage.json +2 -2
  85. package/rules/ruff-f406-undefined-local-with-nested-import-star-usage.json +2 -2
  86. package/rules/ruff-f407-future-feature-not-defined.json +1 -1
  87. package/rules/ruff-f501-percent-format-invalid-format.json +2 -2
  88. package/rules/ruff-f502-percent-format-expected-mapping.json +1 -1
  89. package/rules/ruff-f503-percent-format-expected-sequence.json +1 -1
  90. package/rules/ruff-f504-percent-format-extra-named-arguments.json +1 -1
  91. package/rules/ruff-f505-percent-format-missing-argument.json +1 -1
  92. package/rules/ruff-f506-percent-format-mixed-positional-and-named.json +2 -2
  93. package/rules/ruff-f507-percent-format-positional-count-mismatch.json +2 -2
  94. package/rules/ruff-f508-percent-format-star-requires-sequence.json +2 -2
  95. package/rules/ruff-f509-percent-format-unsupported-format-character.json +2 -2
  96. package/rules/ruff-f521-string-dot-format-invalid-format.json +1 -1
  97. package/rules/ruff-f522-string-dot-format-extra-named-arguments.json +2 -2
  98. package/rules/ruff-f523-string-dot-format-extra-positional-arguments.json +1 -1
  99. package/rules/ruff-f524-string-dot-format-missing-arguments.json +1 -1
  100. package/rules/ruff-f525-string-dot-format-mixing-automatic.json +1 -1
  101. package/rules/ruff-f541-f-string-missing-placeholders.json +3 -3
  102. package/rules/ruff-f601-multi-value-repeated-key-literal.json +1 -1
  103. package/rules/ruff-f602-multi-value-repeated-key-variable.json +2 -2
  104. package/rules/ruff-f622-multiple-starred-expressions.json +1 -1
  105. package/rules/ruff-f632-is-literal.json +222 -5
  106. package/rules/ruff-f633-invalid-print-syntax.json +2 -2
  107. package/rules/ruff-f701-break-outside-loop.json +1 -1
  108. package/rules/ruff-f702-continue-outside-loop.json +1 -1
  109. package/rules/ruff-f706-return-outside-function.json +1 -1
  110. package/rules/ruff-f707-default-except-not-last.json +3 -3
  111. package/rules/ruff-f822-undefined-export.json +1 -1
  112. package/rules/ruff-f823-undefined-local.json +2 -2
  113. package/rules/ruff-f842-unused-annotation.json +1 -1
  114. package/rules/ruff-f901-raise-not-implemented.json +1 -1
  115. package/rules/ruff-pie794-duplicate-class-field-definition.json +1 -1
  116. package/rules/ruff-pie796-non-unique-enums.json +1 -1
  117. package/rules/ruff-pie800-unnecessary-spread.json +1 -1
  118. package/rules/ruff-pie804-unnecessary-dict-kwargs.json +1 -1
  119. package/rules/ruff-pie807-reimplemented-container-builtin.json +1 -1
  120. package/rules/ruff-pie810-multiple-starts-ends-with.json +2 -2
  121. package/rules/ruff-ret501-unnecessary-return-none.json +1 -1
  122. package/rules/ruff-ret502-implicit-return-value.json +2 -2
  123. package/rules/ruff-ret505-superfluous-else-return.json +1 -1
  124. package/rules/ruff-ret506-superfluous-else-raise.json +1 -1
  125. package/rules/ruff-ret507-superfluous-else-continue.json +1 -1
  126. package/rules/ruff-ret508-superfluous-else-break.json +1 -1
  127. package/rules/ruff-sim101-duplicate-isinstance-call.json +1 -1
  128. package/rules/ruff-sim107-return-in-try-except-finally.json +2 -2
  129. package/rules/ruff-sim109-compare-with-tuple.json +1 -1
  130. package/rules/ruff-sim112-uncapitalized-environment-variables.json +3 -3
  131. package/rules/ruff-sim113-enumerate-for-loop.json +1 -1
  132. package/rules/ruff-sim208-double-negation.json +1 -1
  133. package/rules/ruff-sim210-if-expr-with-true-false.json +1 -1
  134. package/rules/ruff-sim211-if-expr-with-false-true.json +1 -1
  135. package/rules/ruff-sim212-if-expr-with-twisted-arms.json +2 -2
  136. package/rules/ruff-sim300-yoda-conditions.json +3 -3
  137. package/rules/ruff-sim905-split-static-string.json +1 -1
  138. package/rules/ruff-sim910-dict-get-with-none-default.json +1 -1
  139. package/rules/ruff-t100-debugger.json +3 -3
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f622-multiple-starred-expressions",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F622 (multiple-starred-expressions, a semantic syntax error) with default settings: a tuple or list assignment target (assignment, `for`, comprehension `for`, `with ... as`), at any nesting, with two or more starred elements of its own. Reported on the target tuple or list, parentheses included.",
6
+ "description": "Use at most one starred element in each Python unpacking target; two in the same target is a syntax error.",
7
7
  "scope": { "include": ["**/*"], "exclude": [] },
8
8
  "clauses": [
9
9
  {
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "format": "rerail.policy/v1",
3
3
  "id": "ruff-f632-is-literal",
4
- "revision": 1,
4
+ "revision": 2,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F632 (is-literal) with default settings: `is` or `is not` with an operand that is a non-singleton constant (string, bytes or number literal, tuple of constants) or a list, set or dict display or comprehension, one finding per offending operator reported on the whole comparison, as in Ruff; also a comparison inside a string Ruff parses as a type definition (a string annotation, `cast`/`TypeVar` arguments, `List[\"...\"]`), reported on the comparison inside the string, once per offending operator; strings nested in one (`List['1 is x']` inside a string annotation) are read too. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/F632.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Use == or != instead of is or is not to compare literal values; the identity of such values is unreliable.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "clauses": [
14
14
  {
15
- "id": "is-literal",
15
+ "id": "is-literal-is",
16
16
  "forbid": {
17
17
  "ast": {
18
18
  "language": "python",
@@ -150,7 +150,7 @@
150
150
  ]
151
151
  },
152
152
  "is-literal-op": {
153
- "regex": "^is(?:[\\s\\\\]+not)?$",
153
+ "regex": "^is$",
154
154
  "any": [
155
155
  {
156
156
  "follows": {
@@ -217,7 +217,224 @@
217
217
  "violation": {
218
218
  "anchor": "capture.C",
219
219
  "code": "F632",
220
- "message": "Use `==` to compare constant literals",
220
+ "message": "Use `==` instead of `is` to compare this literal value.",
221
+ "each": "O",
222
+ "suppress": {
223
+ "noqa": {
224
+ "codes": [
225
+ "F632"
226
+ ]
227
+ }
228
+ }
229
+ }
230
+ },
231
+ {
232
+ "id": "is-literal-is-not",
233
+ "forbid": {
234
+ "ast": {
235
+ "language": "python",
236
+ "utils": {
237
+ "constant": {
238
+ "any": [
239
+ {
240
+ "kind": "string",
241
+ "not": {
242
+ "has": {
243
+ "stopBy": "end",
244
+ "kind": "interpolation"
245
+ }
246
+ }
247
+ },
248
+ {
249
+ "kind": "concatenated_string",
250
+ "not": {
251
+ "has": {
252
+ "stopBy": "end",
253
+ "kind": "interpolation"
254
+ }
255
+ }
256
+ },
257
+ {
258
+ "kind": "integer"
259
+ },
260
+ {
261
+ "kind": "float"
262
+ },
263
+ {
264
+ "kind": "none"
265
+ },
266
+ {
267
+ "kind": "true"
268
+ },
269
+ {
270
+ "kind": "false"
271
+ },
272
+ {
273
+ "kind": "ellipsis"
274
+ },
275
+ {
276
+ "kind": "parenthesized_expression",
277
+ "has": {
278
+ "stopBy": "neighbor",
279
+ "matches": "constant"
280
+ }
281
+ },
282
+ {
283
+ "kind": "tuple",
284
+ "not": {
285
+ "has": {
286
+ "stopBy": "neighbor",
287
+ "not": {
288
+ "any": [
289
+ {
290
+ "matches": "constant"
291
+ },
292
+ {
293
+ "regex": "^[(),]$"
294
+ }
295
+ ]
296
+ }
297
+ }
298
+ }
299
+ }
300
+ ]
301
+ },
302
+ "singleton": {
303
+ "any": [
304
+ {
305
+ "kind": "none"
306
+ },
307
+ {
308
+ "kind": "true"
309
+ },
310
+ {
311
+ "kind": "false"
312
+ },
313
+ {
314
+ "kind": "ellipsis"
315
+ },
316
+ {
317
+ "kind": "parenthesized_expression",
318
+ "has": {
319
+ "stopBy": "neighbor",
320
+ "matches": "singleton"
321
+ }
322
+ }
323
+ ]
324
+ },
325
+ "constant-non-singleton": {
326
+ "all": [
327
+ {
328
+ "matches": "constant"
329
+ },
330
+ {
331
+ "not": {
332
+ "matches": "singleton"
333
+ }
334
+ }
335
+ ]
336
+ },
337
+ "literal-operand": {
338
+ "any": [
339
+ {
340
+ "matches": "constant-non-singleton"
341
+ },
342
+ {
343
+ "kind": "set"
344
+ },
345
+ {
346
+ "kind": "set_comprehension"
347
+ },
348
+ {
349
+ "kind": "list"
350
+ },
351
+ {
352
+ "kind": "list_comprehension"
353
+ },
354
+ {
355
+ "kind": "dictionary"
356
+ },
357
+ {
358
+ "kind": "dictionary_comprehension"
359
+ },
360
+ {
361
+ "kind": "parenthesized_expression",
362
+ "has": {
363
+ "stopBy": "neighbor",
364
+ "matches": "literal-operand"
365
+ }
366
+ }
367
+ ]
368
+ },
369
+ "is-literal-op": {
370
+ "regex": "^is[\\s\\\\]+not$",
371
+ "any": [
372
+ {
373
+ "follows": {
374
+ "stopBy": "neighbor",
375
+ "matches": "literal-operand"
376
+ }
377
+ },
378
+ {
379
+ "precedes": {
380
+ "stopBy": "neighbor",
381
+ "matches": "literal-operand"
382
+ }
383
+ }
384
+ ]
385
+ },
386
+ "is-literal-in-string": {
387
+ "any": [
388
+ {
389
+ "kind": "string"
390
+ },
391
+ {
392
+ "kind": "concatenated_string"
393
+ }
394
+ ],
395
+ "parse": {
396
+ "grammar": "annotation",
397
+ "has": {
398
+ "stopBy": "end",
399
+ "any": [
400
+ {
401
+ "kind": "comparison_operator",
402
+ "has": {
403
+ "stopBy": "neighbor",
404
+ "matches": "is-literal-op",
405
+ "capture": "O"
406
+ },
407
+ "capture": "C"
408
+ },
409
+ {
410
+ "matches": "is-literal-in-string"
411
+ }
412
+ ]
413
+ }
414
+ }
415
+ }
416
+ },
417
+ "rule": {
418
+ "any": [
419
+ {
420
+ "matches": "is-literal-op",
421
+ "inside": {
422
+ "stopBy": "neighbor",
423
+ "kind": "comparison_operator",
424
+ "pattern": "$C"
425
+ }
426
+ },
427
+ {
428
+ "matches": "is-literal-in-string"
429
+ }
430
+ ]
431
+ }
432
+ }
433
+ },
434
+ "violation": {
435
+ "anchor": "capture.C",
436
+ "code": "F632",
437
+ "message": "Use `!=` instead of `is not` to compare this literal value.",
221
438
  "each": "O",
222
439
  "suppress": {
223
440
  "noqa": {
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f633-invalid-print-syntax",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F633 (invalid-print-syntax) with default settings: the left operand of `>>` when it resolves to the builtin `print` (or `builtins.print`), reported on `print`. tree-sitter-python parses a statement `print >> f, x` as a Python 2 print statement whose `print` is a keyword token, not a name reference, so name resolution cannot be asked there; that form falls back to a file-wide test: no binding of `print` anywhere in the file (assignment, loop, with/except and walrus targets, def/class names, parameters, imports, global/nonlocal).",
6
+ "description": "Use print()'s file argument instead of Python 2's >> redirection, which raises TypeError with the print function.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -285,7 +285,7 @@
285
285
  "violation": {
286
286
  "anchor": "witness.span",
287
287
  "code": "F633",
288
- "message": "Use of `>>` is invalid with `print` function",
288
+ "message": "Replace `>>` with print()'s `file=` argument, as in `print(msg, file=sys.stderr)`.",
289
289
  "suppress": {
290
290
  "noqa": {
291
291
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f701-break-outside-loop",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F701 (break-outside-loop, a semantic syntax error) with default settings: `break` with no enclosing `for`/`while` body between it and the nearest function or class definition. A loop's `else` block does not count as inside that loop.",
6
+ "description": "Keep break inside a for or while loop body; outside one (including a loop's else block) it is a Python syntax error.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f702-continue-outside-loop",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F702 (continue-outside-loop, a semantic syntax error) with default settings: `continue` with no enclosing `for`/`while` body between it and the nearest function or class definition. A loop's `else` block does not count as inside that loop.",
6
+ "description": "Keep continue inside a for or while loop body; outside one (including a loop's else block) it is a Python syntax error.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f706-return-outside-function",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F706 (return-outside-function, a semantic syntax error) with default settings: `return` whose nearest enclosing function or class body is not a function body (module level, or directly in a class body).",
6
+ "description": "Keep return inside a function; at module level or directly in a class body it is a Python syntax error.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "format": "rerail.policy/v1",
3
3
  "id": "ruff-f707-default-except-not-last",
4
- "revision": 1,
4
+ "revision": 2,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F707 (default-except-not-last) with default settings: a bare `except:` handler followed by another handler of the same `try`. Reported on the `except` keyword.",
6
+ "description": "Put a bare except handler last in its try statement; Python rejects any handler after it.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -36,7 +36,7 @@
36
36
  "violation": {
37
37
  "anchor": "witness.span",
38
38
  "code": "F707",
39
- "message": "An `except` block as not the last exception handler",
39
+ "message": "Move this bare `except:` handler after all typed handlers; a bare handler must be last.",
40
40
  "suppress": {
41
41
  "noqa": {
42
42
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f822-undefined-export",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F822 (undefined-export) with default settings, on the engine's name resolution (M10a `resolves.unresolved` on `__all__` entries): a string entry of a static module `__all__` definition (Ruff's extract_dunder_all_names) (an implicit concatenation is one entry) that names no module binding (a bare annotation included) and no builtin, in a module without a star import. `__init__.py` is exempt (Ruff reports it only in preview). Reported on the string.",
6
+ "description": "List only names the module actually defines in its __all__ (outside __init__.py); an undefined entry breaks star imports.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f823-undefined-local",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F823 (undefined-local) with default settings, on the engine's name resolution (M10a `resolves.beforeLocal`, Ruff's undefined_local): a function's first read of a name that resolves to an enclosing function's or the module's binding which the function's own later binding of the name shadows, where that binding is the function's first and latest of the name (not `global`, `nonlocal` or `del`). Reported on the read. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/F823.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Don't read a variable before the function assigns it, even when an outer scope has the same name; Python raises UnboundLocalError.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -28,7 +28,7 @@
28
28
  "violation": {
29
29
  "anchor": "witness.span",
30
30
  "code": "F823",
31
- "message": "Local variable `$N` referenced before assignment",
31
+ "message": "Assign `$N` before reading it here, or declare it `global` or `nonlocal` if you meant the outer variable.",
32
32
  "suppress": {
33
33
  "noqa": {
34
34
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f842-unused-annotation",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F842 (unused-annotation) with default settings (`dummy-variable-rgx` = `^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$`), on the engine's usedness (M10a `binds` with form `annotation`, Ruff's unused_annotation): the latest binding of a name in a function or lambda scope that is a bare annotation (`x: int`, `(x): int`) nothing reads, not a dummy name. Names in strings Ruff parses as type definitions are reads (M11a).",
6
+ "description": "Remove local variables that are annotated but never assigned or read; the annotation alone does nothing.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f901-raise-not-implemented",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F901 (raise-not-implemented) with default settings: the exception of a `raise` (not its `from` cause) that is the name `NotImplemented` or a call whose callee is that name, parentheses transparent. Reported on the name. Ruff matches the name itself, not the builtin binding.",
6
+ "description": "Raise NotImplementedError, not NotImplemented; NotImplemented is a comparison sentinel and raising it is a TypeError.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-pie794-duplicate-class-field-definition",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's PIE794 (duplicate-class-field-definition): in a class body, an assignment or annotated assignment to a name `N` whose value does not mention `N`, after an earlier such definition of `N` in the same body.",
6
+ "description": "Define each class field once; a later definition silently replaces the earlier one.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-pie796-non-unique-enums",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's PIE796 (non-unique-enums): in a class with an `enum.Enum` base, a plain assignment whose value equals the value of an earlier assignment in the same body as Ruff's ComparableExpr (`text: \"structure\"`: literals by type and value, `1 == 0x1`, `'a' == \"a\"`, `-1 == -(1)`, not `1 == 1.0 == True`; names compared without NFKC normalization); `enum.auto()` values (alone or in a tuple) are skipped, and in stubs (`.pyi`) so are `...` and `typing.cast(T, ...)`. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/PIE796.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it, and its `.py`/`.pyi` split read per file (`ast.file.path`): the suite's `select_when` gate holds wherever a matching file exists anywhere in the workspace, so in a repository it would read stubs as modules and modules as stubs.",
6
+ "description": "Give each Enum member a unique value; a duplicate becomes an alias of the earlier member instead of a new one.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-pie800-unnecessary-spread",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's PIE800 (unnecessary-spread): a dict display spread with `**` into another dict display, reported on the inner dict (inside any parentheses).",
6
+ "description": "Write the entries directly instead of spreading a dict literal into another Python dict literal.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-pie804-unnecessary-dict-kwargs",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's PIE804 (unnecessary-dict-kwargs): a call argument `**{...}` whose dict display is a single `**x` spread, empty, or has only keys that are str literals (not bytes, f- or t-strings; escapes decoded, implicit concatenations joined) whose value is a Python identifier (not a keyword). Reported on the `**` argument.",
6
+ "description": "Pass keyword arguments directly instead of unpacking a dict literal into a Python call.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-pie807-reimplemented-container-builtin",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's PIE807 (reimplemented-container-builtin): a parameterless `lambda` whose body is an empty list or dict display.",
6
+ "description": "Use list or dict directly instead of a lambda that returns an empty list or dict, such as for a default factory.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-pie810-multiple-starts-ends-with",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's PIE810 (multiple-starts-ends-with): an `or` chain with two or more operands `R.startswith(x)` (or two `R.endswith(x)`) on the same name `R`, each with one positional argument and no keywords, where the argument is not a name bound to a tuple (Ruff's is_bound_to_tuple through `resolves.binding`, read as lookup_symbol does with `stopAtGlobal`: a `def`'s `*args`, a tuple-typed value, `tuple(...)`, or a `tuple`/`Tuple` annotation or return annotation). Reported on the whole chain, once per such group.",
6
+ "description": "Pass a tuple to one startswith() or endswith() call instead of or-ing several calls on the same string.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -570,7 +570,7 @@
570
570
  "violation": {
571
571
  "anchor": "witness.span",
572
572
  "code": "PIE810",
573
- "message": "Call `$M` once with a `tuple`",
573
+ "message": "Call `$M` once with a tuple of all the prefixes or suffixes instead of or-ing several calls.",
574
574
  "each": "FIRST",
575
575
  "suppress": {
576
576
  "noqa": {
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-ret501-unnecessary-return-none",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's RET501 (unnecessary-return-none): `return None` in a function whose every `return` is bare or returns `None` (nested functions and classes are separate; generators and functions whose body is a lone `return` are skipped), unless the function has a return annotation other than `None` or a property decorator (`property`, `enum.property`, `functools.cached_property`, `abc.abstractproperty`, `types.DynamicClassAttribute`, resolved through the file's bindings and imports). Reported on the `return` statement.",
6
+ "description": "Use a bare return instead of return None in Python functions that never return anything else.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-ret502-implicit-return-value",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's RET502 (implicit-return-value): a bare `return` in a function that also has a `return` with a value other than `None` (nested functions and classes are separate; generators and functions whose body is a lone `return` are skipped), reported on the `return`.",
6
+ "description": "Use return None instead of a bare return in Python functions that also return a value; make the None result explicit.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -149,7 +149,7 @@
149
149
  "violation": {
150
150
  "anchor": "witness.span",
151
151
  "code": "RET502",
152
- "message": "Do not implicitly `return None` in function able to return non-`None` value",
152
+ "message": "Write `return None` instead of a bare `return`, since this function returns a value elsewhere.",
153
153
  "suppress": {
154
154
  "noqa": {
155
155
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-ret505-superfluous-else-return",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's RET505 (superfluous-else-return): the first `elif`/`else` clause of an `if` statement inside a function whose `if` body has a direct `return` statement and no earlier direct raise/continue/break statement, reported on the `elif`/`else` keyword. As in Ruff, only the `if` body and the first clause are compared, nested functions and classes are separate, and generator functions and functions whose body is a lone `return` are skipped.",
6
+ "description": "Remove the else or elif after an if branch that returns, and dedent its code; the branch already leaves the function.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-ret506-superfluous-else-raise",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's RET506 (superfluous-else-raise): the first `elif`/`else` clause of an `if` statement inside a function whose `if` body has a direct `raise` statement and no earlier direct return/continue/break statement, reported on the `elif`/`else` keyword. As in Ruff, only the `if` body and the first clause are compared, nested functions and classes are separate, and generator functions and functions whose body is a lone `return` are skipped.",
6
+ "description": "Remove the else or elif after an if branch that raises, and dedent its code; the branch already leaves the function.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-ret507-superfluous-else-continue",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's RET507 (superfluous-else-continue): the first `elif`/`else` clause of an `if` statement inside a function whose `if` body has a direct `continue` statement and no earlier direct return/raise/break statement, reported on the `elif`/`else` keyword. As in Ruff, only the `if` body and the first clause are compared, nested functions and classes are separate, and generator functions and functions whose body is a lone `return` are skipped.",
6
+ "description": "Remove the else or elif after an if branch that continues the loop, and dedent its code; the branch already skips ahead.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-ret508-superfluous-else-break",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's RET508 (superfluous-else-break): the first `elif`/`else` clause of an `if` statement inside a function whose `if` body has a direct `break` statement and no earlier direct return/raise/continue statement, reported on the `elif`/`else` keyword. As in Ruff, only the `if` body and the first clause are compared, nested functions and classes are separate, and generator functions and functions whose body is a lone `return` are skipped.",
6
+ "description": "Remove the else or elif after an if branch that breaks out of the loop, and dedent its code; the branch already exits the loop.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-sim101-duplicate-isinstance-call",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's SIM101 (duplicate-isinstance-call): two adjacent operands of one `or` chain that are calls of the builtin `isinstance(T, C)` (exactly two positional arguments, no keywords) with equal targets (Ruff's ComparableExpr, `text: \"structure\"`; names without NFKC normalization), reported on the whole `or` chain once per run of adjacent such calls with equal targets. A parenthesized `or` is its own chain, as in Ruff's AST. `isinstance` must resolve to the builtin (`match_builtin_expr`: the unshadowed name, or `builtins.isinstance` through an import).",
6
+ "description": "Merge isinstance() checks on the same object joined by or into one call with a tuple of types.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-sim107-return-in-try-except-finally",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's SIM107 (return-in-try-except-finally): the first top-level `return` of a `finally` body when the `try` body or an `except` handler body has a top-level `return`.",
6
+ "description": "Don't return from a finally block when the try or except also returns; the finally return silently overrides theirs.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -68,7 +68,7 @@
68
68
  "violation": {
69
69
  "anchor": "witness.span",
70
70
  "code": "SIM107",
71
- "message": "Don't use `return` in `try`-`except` and `finally`",
71
+ "message": "Remove the `return` from the `finally` block; it silently overrides the `return` in `try` or `except`.",
72
72
  "suppress": {
73
73
  "noqa": {
74
74
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-sim109-compare-with-tuple",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's SIM109 (compare-with-tuple): an `or` chain with two or more operands `N == name` (one `==`, both sides names) for the same `N`, anywhere in the chain; not reported when a comment lies inside the chain or follows it on its last line with only white space between (Ruff's has_comments). Reported on the whole `or` chain, once per such name.",
6
+ "description": "Use a membership test against a tuple instead of several or-chained equality checks of the same variable.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "format": "rerail.policy/v1",
3
3
  "id": "ruff-sim112-uncapitalized-environment-variables",
4
- "revision": 1,
4
+ "revision": 2,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's SIM112 (uncapitalized-environment-variables): a str literal (not bytes, an f- or t-string; escapes decoded, implicit concatenations joined) whose value has an ASCII lowercase letter, other than `https_proxy`/`http_proxy`/`no_proxy`, used as `os.environ[...]` or as the first argument of a call resolving to `os.environ.get`/`os.getenv`, after Ruff's traversal has visited an absolute import of `os` (M10a `resolves.seenBefore`). Reported on the string.",
6
+ "description": "Use uppercase names when reading environment variables through os.environ or os.getenv; the lowercase proxy variables are exempt.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -154,7 +154,7 @@
154
154
  "violation": {
155
155
  "anchor": "witness.span",
156
156
  "code": "SIM112",
157
- "message": "Use capitalized environment variable",
157
+ "message": "Uppercase only if the deployment uses that name; preserve intentional lowercase keys because lookups are case-sensitive on POSIX.",
158
158
  "suppress": {
159
159
  "noqa": {
160
160
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-sim113-enumerate-for-loop",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's SIM113 (enumerate-for-loop): `N += 1` as a top-level statement of a non-async `for` body without `continue`, where the binding `N` reads (`resolves.binding`) is a name assignment of `0` (plain, annotated, or an unpacked element of a display, paired by index as Ruff's match_value where the engine gives no value) whose parent statement is the loop's, `N` is bound only once inside the loop (`binds` with `bindings` within the loop: deletions and comprehension walruses count, comprehension targets, nested functions' locals and keyword arguments do not), and no load of `N` outside the loop in its scope, at or after the initial assignment, reads the initial binding (whose references Ruff's rebinding inherits) or a binding inside the loop. The loop and the initial assignment are found again by node identity (`compare` with `text: \"node\"`), so identical loops in one scope stay apart.",
6
+ "description": "Use enumerate() instead of a counter that starts at 0 and is incremented by hand in each pass of a for loop.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"