Normalize inconsistent markdown headings in docstrings (#16364)

I am working on a project that uses ruff linters' docs to generate a
fine-tuning dataset for LLMs.

To achieve this, I first ran the command `ruff rule --all
--output-format json` to retrieve all the rules. Then, I parsed the
explanation field to get these 3 consistent sections:

- `Why is this bad?`
- `What it does`
- `Example`

However, during the initial processing, I noticed that the markdown
headings are not that consistent. For instance:

- In most cases, `Use instead` appears as a normal paragraph within the
`Example` section, but in the file
`crates/ruff_linter/src/rules/flake8_bandit/rules/django_extra.rs` it is
a level-2 heading
- The heading "What it does**?**" is used in some places, while others
consistently use "What it does"
- There are 831 `Example` headings and 65 `Examples`. But all of them
only have one example case

This PR normalized these across all rules.

## Test Plan

CI are passed.
This commit is contained in:
Muspi Merol 2025-02-25 18:12:55 +08:00 committed by GitHub
parent aac79e453a
commit a1a536b2c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 43 additions and 43 deletions

View file

@ -22,7 +22,7 @@ use crate::checkers::ast::Checker;
/// User.objects.all().extra(select={"test": "%secure" % "nos"})
/// ```
///
/// ## Use instead:
/// Use instead:
/// ```python
/// from django.contrib.auth.models import User
///

View file

@ -15,7 +15,7 @@ use crate::checkers::ast::Checker;
/// Using the generator more than once will do nothing on the second usage.
/// If that data is needed later, it should be stored as a list.
///
/// ## Examples:
/// ## Example:
/// ```python
/// import itertools
///

View file

@ -21,7 +21,7 @@ use crate::rules::flake8_comprehensions::fixes;
///
/// In both cases, it's clearer and more efficient to avoid the redundant call.
///
/// ## Examples
/// ## Example
/// ```python
/// reversed(sorted(iterable))
/// ```

View file

@ -17,7 +17,7 @@ use crate::rules::flake8_comprehensions::settings::Settings;
/// literal (`{}`). The former is slower because the name `dict` must be
/// looked up in the global scope in case it has been rebound.
///
/// ## Examples
/// ## Example
/// ```python
/// dict()
/// dict(a=1, b=2)

View file

@ -15,7 +15,7 @@ use crate::rules::flake8_comprehensions::fixes;
/// It's unnecessary to use a dict/list/set comprehension to build a data structure if the
/// elements are unchanged. Wrap the iterable with `dict()`, `list()`, or `set()` instead.
///
/// ## Examples
/// ## Example
/// ```python
/// {a: b for a, b in iterable}
/// [x for x in iterable]

View file

@ -41,7 +41,7 @@ use crate::rules::flake8_comprehensions::fixes;
/// short-circuiting it may not improve performance. (It may even slightly regress performance,
/// though the difference will usually be small.)
///
/// ## Examples
/// ## Example
/// ```python
/// any([x.id for x in bar])
/// all([x.id for x in bar])

View file

@ -19,7 +19,7 @@ use crate::checkers::ast::Checker;
/// Prefer `dict.fromkeys(iterable)` over `{value: None for value in iterable}`,
/// as `dict.fromkeys` is more readable and efficient.
///
/// ## Examples
/// ## Example
/// ```python
/// {a: None for a in iterable}
/// {a: 1 for a in iterable}

View file

@ -17,7 +17,7 @@ use crate::rules::flake8_comprehensions::fixes;
/// the listed functions within an additional `list()`, `set()`, `sorted()`, or
/// `tuple()` call. Doing so is redundant and can be confusing for readers.
///
/// ## Examples
/// ## Example
/// ```python
/// list(tuple(iterable))
/// ```

View file

@ -18,7 +18,7 @@ use super::helpers;
/// there are equivalent comprehensions for these types. Using a
/// comprehension is clearer and more idiomatic.
///
/// ## Examples
/// ## Example
/// ```python
/// dict((x, f(x)) for x in foo)
/// ```

View file

@ -24,7 +24,7 @@ use super::helpers;
/// `list(x for x in foo)`, it's better to use `list(foo)` directly, since it's
/// even more direct.
///
/// ## Examples
/// ## Example
/// ```python
/// list(f(x) for x in foo)
/// list(x for x in foo)

View file

@ -25,7 +25,7 @@ use super::helpers;
/// `set(x for x in foo)`, it's better to use `set(foo)` directly, since it's
/// even more direct.
///
/// ## Examples
/// ## Example
/// ```python
/// set(f(x) for x in foo)
/// set(x for x in foo)

View file

@ -16,7 +16,7 @@ use super::helpers;
/// ## Why is this bad?
/// It is redundant to use a `list()` call around a list comprehension.
///
/// ## Examples
/// ## Example
/// ```python
/// list([f(x) for x in foo])
/// ```

View file

@ -16,7 +16,7 @@ use super::helpers;
/// It's unnecessary to use a list comprehension inside a call to `dict()`,
/// since there is an equivalent comprehension for this type.
///
/// ## Examples
/// ## Example
/// ```python
/// dict([(x, f(x)) for x in foo])
/// ```

View file

@ -17,7 +17,7 @@ use super::helpers;
/// It's unnecessary to use a list comprehension inside a call to `set()`,
/// since there is an equivalent comprehension for this type.
///
/// ## Examples
/// ## Example
/// ```python
/// set([f(x) for x in foo])
/// ```

View file

@ -16,7 +16,7 @@ use super::helpers;
/// It's unnecessary to use a list or tuple literal within a call to `dict()`.
/// It can be rewritten as a dict literal (`{}`).
///
/// ## Examples
/// ## Example
/// ```python
/// dict([(1, 2), (3, 4)])
/// dict(((1, 2), (3, 4)))

View file

@ -16,7 +16,7 @@ use super::helpers;
/// It's unnecessary to use a list or tuple literal within a call to `set()`.
/// Instead, the expression can be rewritten as a set literal.
///
/// ## Examples
/// ## Example
/// ```python
/// set([1, 2])
/// set((1, 2))

View file

@ -19,7 +19,7 @@ use super::helpers;
/// call, since the literal or comprehension syntax already returns a
/// dictionary.
///
/// ## Examples
/// ## Example
/// ```python
/// dict({})
/// dict({"a": 1})

View file

@ -19,7 +19,7 @@ use super::helpers;
/// removed. Otherwise, if a tuple literal is passed in, then it should be
/// rewritten as a list literal.
///
/// ## Examples
/// ## Example
/// ```python
/// list([1, 2])
/// list((1, 2))

View file

@ -27,7 +27,7 @@ use super::helpers;
/// calls. If a list comprehension is found, it should be rewritten as a
/// generator expression.
///
/// ## Examples
/// ## Example
/// ```python
/// tuple([1, 2])
/// tuple((1, 2))

View file

@ -30,7 +30,7 @@ use crate::rules::flake8_comprehensions::fixes;
/// - Instead of `dict(map(lambda v: (v, v ** 2), values))`, use
/// `{v: v ** 2 for v in values}`.
///
/// ## Examples
/// ## Example
/// ```python
/// map(lambda x: x + 1, iterable)
/// ```

View file

@ -13,7 +13,7 @@ use crate::checkers::ast::Checker;
/// into `reversed()`, `set()` or `sorted()` functions as they will change
/// the order of the elements again.
///
/// ## Examples
/// ## Example
/// ```python
/// sorted(iterable[::-1])
/// set(iterable[::-1])

View file

@ -27,7 +27,7 @@ use super::helpers;
/// 6. `def get_absolute_url()`
/// 7. Any custom methods
///
/// ## Examples
/// ## Example
/// ```python
/// from django.db import models
///

View file

@ -145,7 +145,7 @@ impl AlwaysFixableViolation for AssignmentDefaultInStub {
}
}
/// ## What it does?
/// ## What it does
/// Checks for unannotated assignments in stub (`.pyi`) files.
///
/// ## Why is this bad?

View file

@ -16,7 +16,7 @@ use ruff_text_size::Ranged;
/// if the given suffix is not prefixed with a dot
/// or it is a single dot `"."`.
///
/// ## Examples
/// ## Example
///
/// ```python
/// path.with_suffix("py")

View file

@ -12,7 +12,7 @@ use ruff_macros::{derive_message_formats, ViolationMetadata};
/// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getatime()`).
///
/// ## Examples
/// ## Example
/// ```python
/// import os
///

View file

@ -12,7 +12,7 @@ use ruff_macros::{derive_message_formats, ViolationMetadata};
/// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getctime()`).
///
/// ## Examples
/// ## Example
/// ```python
/// import os
///

View file

@ -12,7 +12,7 @@ use ruff_macros::{derive_message_formats, ViolationMetadata};
/// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getmtime()`).
///
/// ## Examples
/// ## Example
/// ```python
/// import os
///

View file

@ -12,7 +12,7 @@ use ruff_macros::{derive_message_formats, ViolationMetadata};
/// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getsize()`).
///
/// ## Examples
/// ## Example
/// ```python
/// import os
///

View file

@ -17,7 +17,7 @@ use crate::importer::ImportRequest;
///
/// Prefer newer APIs over deprecated ones.
///
/// ## Examples
/// ## Example
/// ```python
/// import numpy as np
///

View file

@ -19,7 +19,7 @@ use crate::checkers::ast::Checker;
/// Note, however, that `np.bool` and `np.long` were reintroduced in 2.0 with
/// different semantics, and are thus omitted from this rule.
///
/// ## Examples
/// ## Example
/// ```python
/// import numpy as np
///

View file

@ -28,7 +28,7 @@ use crate::checkers::ast::Checker;
/// See the documentation on [Random Sampling] and [NEP 19] for further
/// details.
///
/// ## Examples
/// ## Example
/// ```python
/// import numpy as np
///

View file

@ -31,7 +31,7 @@ use crate::importer::ImportRequest;
/// This rule flags all uses of removed members, along with automatic fixes for
/// any backwards-compatible replacements.
///
/// ## Examples
/// ## Example
/// ```python
/// import numpy as np
///

View file

@ -13,7 +13,7 @@ use crate::checkers::ast::Checker;
/// If a class definition doesn't have any bases, the parentheses are
/// unnecessary.
///
/// ## Examples
/// ## Example
/// ```python
/// class Foo():
/// ...

View file

@ -20,7 +20,7 @@ use crate::checkers::ast::Checker;
/// Omitting type arguments that match the default values can make the code
/// more concise and easier to read.
///
/// ## Examples
/// ## Example
///
/// ```python
/// from collections.abc import Generator, AsyncGenerator

View file

@ -15,7 +15,7 @@ use crate::checkers::ast::Checker;
/// the use of `from_float` and `from_decimal` methods is unnecessary, and
/// should be avoided in favor of the more concise constructor syntax.
///
/// ## Examples
/// ## Example
/// ```python
/// Decimal.from_float(4.2)
/// Decimal.from_float(float("inf"))

View file

@ -19,7 +19,7 @@ use crate::checkers::ast::Checker;
/// which may result in unexpected behavior (e.g., undefined variable
/// accesses).
///
/// ## Examples
/// ## Example
/// ```python
/// assert (x := 0) == 0
/// print(x)

View file

@ -38,7 +38,7 @@ use crate::Locator;
/// keyword to a positional argument will change the behavior of the code, even
/// if the keyword argument was used erroneously.
///
/// ## Examples
/// ## Example
/// ```python
/// defaultdict(default_factory=int)
/// defaultdict(default_factory=list)

View file

@ -29,7 +29,7 @@ use crate::rules::ruff::rules::helpers::{
/// Attributes whose default arguments are `NewType` calls
/// where the original type is immutable are ignored.
///
/// ## Examples
/// ## Example
/// ```python
/// from dataclasses import dataclass
///

View file

@ -26,7 +26,7 @@ use super::suppression_comment_visitor::{
/// Suppression comments that do not actually prevent formatting could cause unintended changes
/// when the formatter is run.
///
/// ## Examples
/// ## Example
/// In the following example, all suppression comments would cause
/// a rule violation.
///

View file

@ -22,7 +22,7 @@ use crate::rules::ruff::rules::helpers::{dataclass_kind, is_class_var_annotation
/// If the default value is intended to be mutable, it must be annotated with
/// `typing.ClassVar`; otherwise, a `ValueError` will be raised.
///
/// ## Examples
/// ## Example
/// ```python
/// from dataclasses import dataclass
///

View file

@ -17,7 +17,7 @@ use crate::checkers::ast::Checker;
/// without having to check if the dictionary contains the relevant key,
/// returning `None` if the key is not present.
///
/// ## Examples
/// ## Example
/// ```python
/// if "key" in dct and dct["key"]:
/// ...

View file

@ -10,7 +10,7 @@ use ruff_text_size::Ranged;
/// ## Why is this bad?
/// It's unnecessary to use an empty literal as a deque's iterable, since this is already the default behavior.
///
/// ## Examples
/// ## Example
///
/// ```python
/// from collections import deque

View file

@ -18,7 +18,7 @@ use crate::rules::fastapi::rules::is_fastapi_route;
/// contexts where that function may be called. In some cases, labeling a function `async` is
/// semantically meaningful (e.g. with the trio library).
///
/// ## Examples
/// ## Example
/// ```python
/// async def foo():
/// bar()