@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
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "format": "rerail.policy/v1",
3
3
  "id": "ruff-e711-none-comparison",
4
- "revision": 1,
4
+ "revision": 2,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's E711 (none-comparison) with default settings: `None` compared with `==` or `!=`, reported on the `None` literal (inside any parentheses). The first operand is checked when the second is not a non-singleton constant; each later `None` when the operand before its operator is not one (Ruff's `is_constant_non_singleton`: string, bytes and number literals, and tuples of constants). Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/E711.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Use is None or is not None instead of == or != to compare with None; equality can be overridden and gives surprising results.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "clauses": [
14
14
  {
15
- "id": "none-comparison",
15
+ "id": "none-comparison-equal",
16
16
  "forbid": {
17
17
  "ast": {
18
18
  "language": "python",
@@ -113,7 +113,7 @@
113
113
  {
114
114
  "precedes": {
115
115
  "stopBy": "neighbor",
116
- "regex": "^(==|!=)$",
116
+ "regex": "^==$",
117
117
  "precedes": {
118
118
  "stopBy": "neighbor",
119
119
  "not": {
@@ -127,7 +127,7 @@
127
127
  {
128
128
  "follows": {
129
129
  "stopBy": "neighbor",
130
- "regex": "^(==|!=)$",
130
+ "regex": "^==$",
131
131
  "follows": {
132
132
  "stopBy": "neighbor",
133
133
  "not": {
@@ -185,7 +185,191 @@
185
185
  "violation": {
186
186
  "anchor": "witness.span",
187
187
  "code": "E711",
188
- "message": "Comparison to `None` should be `cond is None`",
188
+ "message": "Use `is None` instead of `== None` for this comparison.",
189
+ "suppress": {
190
+ "noqa": {
191
+ "codes": [
192
+ "E711"
193
+ ]
194
+ }
195
+ }
196
+ }
197
+ },
198
+ {
199
+ "id": "none-comparison-not-equal",
200
+ "forbid": {
201
+ "ast": {
202
+ "language": "python",
203
+ "utils": {
204
+ "constant": {
205
+ "any": [
206
+ {
207
+ "kind": "string",
208
+ "not": {
209
+ "has": {
210
+ "stopBy": "end",
211
+ "kind": "interpolation"
212
+ }
213
+ }
214
+ },
215
+ {
216
+ "kind": "concatenated_string",
217
+ "not": {
218
+ "has": {
219
+ "stopBy": "end",
220
+ "kind": "interpolation"
221
+ }
222
+ }
223
+ },
224
+ {
225
+ "kind": "integer"
226
+ },
227
+ {
228
+ "kind": "float"
229
+ },
230
+ {
231
+ "kind": "none"
232
+ },
233
+ {
234
+ "kind": "true"
235
+ },
236
+ {
237
+ "kind": "false"
238
+ },
239
+ {
240
+ "kind": "ellipsis"
241
+ },
242
+ {
243
+ "kind": "parenthesized_expression",
244
+ "has": {
245
+ "stopBy": "neighbor",
246
+ "matches": "constant"
247
+ }
248
+ },
249
+ {
250
+ "kind": "tuple",
251
+ "not": {
252
+ "has": {
253
+ "stopBy": "neighbor",
254
+ "not": {
255
+ "any": [
256
+ {
257
+ "matches": "constant"
258
+ },
259
+ {
260
+ "regex": "^[(),]$"
261
+ }
262
+ ]
263
+ }
264
+ }
265
+ }
266
+ }
267
+ ]
268
+ },
269
+ "constant-non-singleton": {
270
+ "all": [
271
+ {
272
+ "matches": "constant"
273
+ },
274
+ {
275
+ "not": {
276
+ "matches": "singleton"
277
+ }
278
+ }
279
+ ]
280
+ },
281
+ "compared-operand": {
282
+ "inside": {
283
+ "stopBy": "neighbor",
284
+ "kind": "comparison_operator"
285
+ },
286
+ "any": [
287
+ {
288
+ "all": [
289
+ {
290
+ "not": {
291
+ "follows": {
292
+ "stopBy": "neighbor",
293
+ "regex": "(?s)."
294
+ }
295
+ }
296
+ },
297
+ {
298
+ "precedes": {
299
+ "stopBy": "neighbor",
300
+ "regex": "^!=$",
301
+ "precedes": {
302
+ "stopBy": "neighbor",
303
+ "not": {
304
+ "matches": "constant-non-singleton"
305
+ }
306
+ }
307
+ }
308
+ }
309
+ ]
310
+ },
311
+ {
312
+ "follows": {
313
+ "stopBy": "neighbor",
314
+ "regex": "^!=$",
315
+ "follows": {
316
+ "stopBy": "neighbor",
317
+ "not": {
318
+ "matches": "constant-non-singleton"
319
+ }
320
+ }
321
+ }
322
+ }
323
+ ]
324
+ },
325
+ "operand": {
326
+ "any": [
327
+ {
328
+ "matches": "compared-operand"
329
+ },
330
+ {
331
+ "inside": {
332
+ "stopBy": "neighbor",
333
+ "kind": "parenthesized_expression",
334
+ "matches": "operand"
335
+ }
336
+ }
337
+ ]
338
+ },
339
+ "singleton": {
340
+ "any": [
341
+ {
342
+ "kind": "none"
343
+ },
344
+ {
345
+ "kind": "true"
346
+ },
347
+ {
348
+ "kind": "false"
349
+ },
350
+ {
351
+ "kind": "ellipsis"
352
+ },
353
+ {
354
+ "kind": "parenthesized_expression",
355
+ "has": {
356
+ "stopBy": "neighbor",
357
+ "matches": "singleton"
358
+ }
359
+ }
360
+ ]
361
+ }
362
+ },
363
+ "rule": {
364
+ "kind": "none",
365
+ "matches": "operand"
366
+ }
367
+ }
368
+ },
369
+ "violation": {
370
+ "anchor": "witness.span",
371
+ "code": "E711",
372
+ "message": "Use `is not None` instead of `!= None` for this comparison.",
189
373
  "suppress": {
190
374
  "noqa": {
191
375
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-e721-type-comparison",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's E721 (type-comparison): a comparison with an `==` or `!=` operator whose operand on either side is a type (a call whose callee resolves to the builtin `type` or `builtins.type`, or a name from Ruff's builtin type and exception list that resolves to the builtin) while neither side is a dtype (`x.dtype`, or a call of a callee resolving to `numpy.dtype`), reported on the whole comparison once per offending operator (a chained comparison can report twice, as in Ruff).",
6
+ "description": "Use isinstance(), or is and is not, instead of == or != to compare types; equality on types misses subclasses and can be overridden.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-e722-bare-except",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's E722 (bare-except) with default settings: an `except` clause that names no exception type, unless its body re-raises with a bare `raise` statement. Reported on the `except` keyword, as Ruff does. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/E722.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Name the exception types in except clauses instead of a bare except, unless the handler re-raises; a bare except also catches KeyboardInterrupt and SystemExit.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -43,7 +43,7 @@
43
43
  "violation": {
44
44
  "anchor": "witness.span",
45
45
  "code": "E722",
46
- "message": "Do not use bare `except`",
46
+ "message": "Name the exception types this bare except should catch; it also catches KeyboardInterrupt and SystemExit.",
47
47
  "suppress": {
48
48
  "noqa": {
49
49
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-e742-ambiguous-class-name",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's E742 (ambiguous-class-name): a class named `l`, `I` or `O`, reported on the name.",
6
+ "description": "Avoid naming classes l, I or O; in many fonts they are hard to tell apart from 1 and 0.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -33,7 +33,7 @@
33
33
  "violation": {
34
34
  "anchor": "witness.span",
35
35
  "code": "E742",
36
- "message": "Ambiguous class name: `$NAME`",
36
+ "message": "Rename class `$NAME` to a descriptive name; in many fonts it is easy to confuse with 1 or 0.",
37
37
  "suppress": {
38
38
  "noqa": {
39
39
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-e743-ambiguous-function-name",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's E743 (ambiguous-function-name): a function named `l`, `I` or `O`, reported on the name. Includes `async def` and methods.",
6
+ "description": "Avoid naming functions or methods l, I or O; in many fonts they are hard to tell apart from 1 and 0.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -33,7 +33,7 @@
33
33
  "violation": {
34
34
  "anchor": "witness.span",
35
35
  "code": "E743",
36
- "message": "Ambiguous function name: `$NAME`",
36
+ "message": "Rename function `$NAME` to a descriptive name; in many fonts it is easy to confuse with 1 or 0.",
37
37
  "suppress": {
38
38
  "noqa": {
39
39
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f403-undefined-local-with-import-star",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F403 (undefined-local-with-import-star): any `from <module> import *` whose module is not `__future__` (at any depth, whatever the relative level), reported on the whole statement.",
6
+ "description": "Avoid from module import * star imports; they hide where names come from and stop undefined names from being detected.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f405-undefined-local-with-import-star-usage",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F405 (undefined-local-with-import-star-usage) on the engine's name resolution (M10a `resolves.unresolved: \"star\"`): a reference, or a string entry of a module `__all__`, that no binding in scope and no builtin resolves and that a visible star import may bind, reported on the name or the string; and such a name inside a string Ruff parses as a type definition (M11a `parse` with `annotation`, nested strings included), reported on each such name inside the string.",
6
+ "description": "Import names explicitly instead of relying on a star import to define them; names that may only come from a star import can't be checked.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -72,7 +72,7 @@
72
72
  "violation": {
73
73
  "anchor": "capture.NAME",
74
74
  "code": "F405",
75
- "message": "`$NAME` may be undefined, or defined from star imports",
75
+ "message": "Import `$NAME` explicitly from its module; it may only be defined by a star import.",
76
76
  "each": "NAME",
77
77
  "suppress": {
78
78
  "noqa": {
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f406-undefined-local-with-nested-import-star-usage",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F406 (undefined-local-with-nested-import-star-usage): a `from <module> import *` outside module scope, i.e. anywhere inside a function or class body, reported on the whole statement.",
6
+ "description": "Don't use from module import * inside a function or class; star imports are only allowed at module level.",
7
7
  "scope": { "include": ["**/*"], "exclude": [] },
8
8
  "clauses": [
9
9
  {
@@ -25,7 +25,7 @@
25
25
  "violation": {
26
26
  "anchor": "witness.span",
27
27
  "code": "F406",
28
- "message": "`from $MODULE import *` only allowed at module level",
28
+ "message": "Import the needed names from `$MODULE` explicitly; a star import is only allowed at module level.",
29
29
  "suppress": {
30
30
  "noqa": {
31
31
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f407-future-feature-not-defined",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F407 (future-feature-not-defined): a name imported from `__future__` (also through a relative `from .__future__`, matched by the module's text with `resolves.imported` and `relative: \"text\"`, as Ruff ignores the level) that is not one of CPython's future features (`is_known_future_feature` in ruff_python_parser's semantic_errors.rs), reported on the alias (`name as alias` included) or on the `*` of a star import.",
6
+ "description": "Import only real feature names from __future__; an unknown feature name is a syntax error.",
7
7
  "scope": { "include": ["**/*"], "exclude": [] },
8
8
  "clauses": [
9
9
  {
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f501-percent-format-invalid-format",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F501 (percent-format-invalid-format): a `%`-format string the parser refuses for any reason but an unsupported format character (an incomplete specifier, an unclosed mapping key, a width or precision too big). The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) left of `%`, read with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser).",
6
+ "description": "Fix malformed %-format strings, such as incomplete specifiers or unclosed %(key) names; they raise an error at run time.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -74,7 +74,7 @@
74
74
  "violation": {
75
75
  "anchor": "witness.span",
76
76
  "code": "F501",
77
- "message": "`%`-format string has invalid format string",
77
+ "message": "Fix this malformed %-format string, such as an incomplete specifier or an unclosed %(key) name.",
78
78
  "suppress": {
79
79
  "noqa": {
80
80
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f502-percent-format-expected-mapping",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F502 (percent-format-expected-mapping): a valid `%`-format string with a `%(key)` placeholder applied to a list, tuple or set display, a list or set comprehension or a generator. The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) left of `%`, read with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser).",
6
+ "description": "Pass a mapping, not a list, tuple or set, to a %-format string that uses %(key) placeholders; the call fails at run time.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f503-percent-format-expected-sequence",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F503 (percent-format-expected-sequence): a valid `%`-format string consuming more than one positional value (placeholders without a key, and `*` widths and precisions) applied to a dict display or comprehension. The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) left of `%`, read with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser).",
6
+ "description": "Pass a tuple, not a dict, to a %-format string with several positional placeholders; the call fails at run time.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f504-percent-format-extra-named-arguments",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F504 (percent-format-extra-named-arguments): a valid `%`-format string without positional placeholders applied to a dict display without `**` with a string-literal key no `%(key)` placeholder names. `formatArgs` reads the format string left of `%` (a str literal with no f/t/b prefix, implicit concatenations joined, escapes decoded, parentheses transparent) with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser), and the right operand as Ruff's strings.rs does.",
6
+ "description": "Remove dict keys that no %(key) placeholder in the %-format string uses; an unused key usually means a typo or a stale argument.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f505-percent-format-missing-argument",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F505 (percent-format-missing-argument): a valid `%`-format string without positional placeholders applied to a dict display without `**`, all of whose keys are string literals, that passes no value for some `%(key)` placeholder. `formatArgs` reads the format string left of `%` (a str literal with no f/t/b prefix, implicit concatenations joined, escapes decoded, parentheses transparent) with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser), and the right operand as Ruff's strings.rs does.",
6
+ "description": "Supply a value for every %(key) placeholder in a %-format string; a missing key raises KeyError at run time.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f506-percent-format-mixed-positional-and-named",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F506 (percent-format-mixed-positional-and-named): a valid `%`-format string with both a `%(key)` placeholder and a positional value (a placeholder without a key, or a `*` width or precision). The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) left of `%`, read with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser).",
6
+ "description": "Don't mix %(key) placeholders and positional placeholders in one %-format string; Python cannot format it.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -100,7 +100,7 @@
100
100
  "violation": {
101
101
  "anchor": "witness.span",
102
102
  "code": "F506",
103
- "message": "`%`-format string has mixed positional and named placeholders",
103
+ "message": "Use only %(key) placeholders or only positional ones in this format string; Python cannot format a mix.",
104
104
  "suppress": {
105
105
  "noqa": {
106
106
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f507-percent-format-positional-count-mismatch",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F507 (percent-format-positional-count-mismatch): a valid `%`-format string without `%(key)` placeholders whose positional values differ in number from a tuple display without starred items, or, with any count but one, from a right operand Ruff's ResolvedPythonType infers as one non-tuple value; with no placeholder, any right operand but a tuple display or one Ruff types as a tuple (`(1,) + (2,)`). `formatArgs` reads the format string left of `%` (a str literal with no f/t/b prefix, implicit concatenations joined, escapes decoded, parentheses transparent) with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser), and the right operand as Ruff's strings.rs does. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/F507.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Match the number of %-format placeholders to the number of values supplied; a mismatch raises TypeError at run time.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -64,7 +64,7 @@
64
64
  "violation": {
65
65
  "anchor": "witness.span",
66
66
  "code": "F507",
67
- "message": "`%`-format string placeholder count differs from the substitution count",
67
+ "message": "Make the number of values match the placeholders in this %-format string; a mismatch raises TypeError.",
68
68
  "suppress": {
69
69
  "noqa": {
70
70
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f508-percent-format-star-requires-sequence",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F508 (percent-format-star-requires-sequence): a valid `%`-format string with a `*` width or precision applied to a dict display or comprehension. The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) left of `%`, read with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser).",
6
+ "description": "Pass a tuple, not a dict, to a %-format string that uses a * width or precision; the call fails at run time.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -98,7 +98,7 @@
98
98
  "violation": {
99
99
  "anchor": "witness.span",
100
100
  "code": "F508",
101
- "message": "`%`-format string `*` specifier requires sequence",
101
+ "message": "Pass a tuple instead of a dict to this %-format string; its `*` width or precision takes positional values.",
102
102
  "suppress": {
103
103
  "noqa": {
104
104
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f509-percent-format-unsupported-format-character",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F509 (percent-format-unsupported-format-character): a `%`-format string the parser refuses at an unsupported conversion character. The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) left of `%`, read with the `percentFormat` grammar (a port of ruff_python_literal's cformat parser).",
6
+ "description": "Use only valid conversion characters in Python %-format strings; an unsupported one raises ValueError at runtime.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -72,7 +72,7 @@
72
72
  "violation": {
73
73
  "anchor": "witness.span",
74
74
  "code": "F509",
75
- "message": "`%`-format string has unsupported format character",
75
+ "message": "Replace the unsupported conversion character in this %-format string with a valid one such as `s`, `d`, `r` or `f`.",
76
76
  "suppress": {
77
77
  "noqa": {
78
78
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f521-string-dot-format-invalid-format",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F521 (string-dot-format-invalid-format): a `.format` call on a str literal the format parser refuses (unmatched braces, fields nested deeper than one level, an empty attribute or index, an unclosed `[`, a bad conversion or format spec). The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) receiving `.format`, read with the `braceFormat` grammar (a port of ruff_python_literal's format parser as pyflakes' FormatSummary reads it).",
6
+ "description": "Keep str.format() strings well-formed, with balanced braces and valid fields and format specs; a malformed one raises ValueError at runtime.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f522-string-dot-format-extra-named-arguments",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F522 (string-dot-format-extra-named-arguments): a `.format` call without `**` on a valid format string, passing a keyword argument no named field (top level or nested in a spec) reads. `formatArgs` reads the format string receiving `.format` (a str literal with no f/t/b prefix, implicit concatenations joined, escapes decoded, parentheses transparent) with the `braceFormat` grammar (a port of ruff_python_literal's format parser as pyflakes' FormatSummary reads it), and the call's arguments as Ruff's strings.rs does.",
6
+ "description": "Remove keyword arguments to str.format() that no named placeholder in the string uses; they are silently ignored.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -32,7 +32,7 @@
32
32
  "violation": {
33
33
  "anchor": "witness.span",
34
34
  "code": "F522",
35
- "message": "`.format` call has unused named argument(s)",
35
+ "message": "Remove the keyword arguments that no named placeholder in this str.format() string uses.",
36
36
  "suppress": {
37
37
  "noqa": {
38
38
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f523-string-dot-format-extra-positional-arguments",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F523 (string-dot-format-extra-positional-arguments): a `.format` call on a valid format string with a positional argument (not starred; counted by syntactic index, past a starred one too) that no automatic or numbered field reads. `formatArgs` reads the format string receiving `.format` (a str literal with no f/t/b prefix, implicit concatenations joined, escapes decoded, parentheses transparent) with the `braceFormat` grammar (a port of ruff_python_literal's format parser as pyflakes' FormatSummary reads it), and the call's arguments as Ruff's strings.rs does. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/F523.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Remove positional arguments to str.format() that no placeholder in the string uses; they are silently ignored.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f524-string-dot-format-missing-arguments",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F524 (string-dot-format-missing-arguments): a `.format` call without `*` or `**` on a valid format string with a field (top level or nested in a spec) whose index is past the positional arguments or whose name no keyword argument passes. `formatArgs` reads the format string receiving `.format` (a str literal with no f/t/b prefix, implicit concatenations joined, escapes decoded, parentheses transparent) with the `braceFormat` grammar (a port of ruff_python_literal's format parser as pyflakes' FormatSummary reads it), and the call's arguments as Ruff's strings.rs does. Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/F524.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Pass an argument for every placeholder in a str.format() string; a missing one raises IndexError or KeyError at runtime.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f525-string-dot-format-mixing-automatic",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F525 (string-dot-format-mixing-automatic): a `.format` call on a valid format string with both an automatically numbered field (`{}`) and a manually numbered one (`{0}`), nested fields in specs included. The format string is a str literal (no f/t/b prefix; implicit concatenations joined, escapes decoded, parentheses transparent) receiving `.format`, read with the `braceFormat` grammar (a port of ruff_python_literal's format parser as pyflakes' FormatSummary reads it).",
6
+ "description": "Don't mix automatic and manually numbered fields in one str.format() string; Python raises ValueError at runtime.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "format": "rerail.policy/v1",
3
3
  "id": "ruff-f541-f-string-missing-placeholders",
4
- "revision": 1,
4
+ "revision": 2,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F541 (f-string-missing-placeholders) with default settings: every f-string part of a string expression (an implicit concatenation counts as one expression) when no f-string part of that expression has a replacement field. `{{`/`}}` escapes are not placeholders; nested f-strings inside a replacement field or format spec are their own expressions.",
6
+ "description": "Remove the f prefix from Python f-strings that have no placeholders; it suggests interpolation that never happens.",
7
7
  "scope": { "include": ["**/*"], "exclude": [] },
8
8
  "clauses": [
9
9
  {
@@ -38,7 +38,7 @@
38
38
  "violation": {
39
39
  "anchor": "witness.span",
40
40
  "code": "F541",
41
- "message": "f-string without any placeholders",
41
+ "message": "Remove the `f` prefix and unescape doubled braces to keep this string's runtime value unchanged.",
42
42
  "suppress": {
43
43
  "noqa": {
44
44
  "codes": [
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f601-multi-value-repeated-key-literal",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F601 (multi-value-repeated-key-literal) with default settings: a literal dictionary key (string, bytes, number, boolean, None, Ellipsis, tuple, f-string, signed number, real +/- imaginary; Ruff's is_literal_key) equal to an earlier key of the same dict display, reported on each repeat (parentheses are transparent). Equality is Ruff's HashableExpr (`compare` `text: \"structure-hash\"`): numbers fold by value (`1 == 1.0 == True`, `1 + 0j == 1`), strings by decoded value, tuples of constants element by element, anything else structurally as ComparableExpr (names without NFKC normalization). Ported from the Ruff conformance suite (rerail/conformance/ruff/rules/F601.json at 3f102adcb), with Ruff's `# noqa` honoured as the Ruff CLI honours it.",
6
+ "description": "Avoid repeating a literal key (or an equal one, like 1 and 1.0) in a Python dict literal; the later value silently overwrites the earlier one.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -3,7 +3,7 @@
3
3
  "id": "ruff-f602-multi-value-repeated-key-variable",
4
4
  "revision": 1,
5
5
  "mode": "steer",
6
- "description": "Port of Ruff's F602 (multi-value-repeated-key-variable) with default settings: a dictionary key that is a bare name equal to an earlier key of the same dict display, reported on each repeat (parentheses transparent).",
6
+ "description": "Avoid repeating the same variable as a key in a Python dict literal; the later value silently overwrites the earlier one.",
7
7
  "scope": {
8
8
  "include": [
9
9
  "**/*"
@@ -109,7 +109,7 @@
109
109
  "violation": {
110
110
  "anchor": "witness.span",
111
111
  "code": "F602",
112
- "message": "Dictionary key `$KEY` repeated",
112
+ "message": "Remove or merge the repeated key `$KEY` in this dict; the later value silently overwrites the earlier one.",
113
113
  "suppress": {
114
114
  "noqa": {
115
115
  "codes": [