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"}) /// User.objects.all().extra(select={"test": "%secure" % "nos"})
/// ``` /// ```
/// ///
/// ## Use instead: /// Use instead:
/// ```python /// ```python
/// from django.contrib.auth.models import User /// 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. /// 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. /// If that data is needed later, it should be stored as a list.
/// ///
/// ## Examples: /// ## Example:
/// ```python /// ```python
/// import itertools /// 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. /// In both cases, it's clearer and more efficient to avoid the redundant call.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// reversed(sorted(iterable)) /// 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 /// literal (`{}`). The former is slower because the name `dict` must be
/// looked up in the global scope in case it has been rebound. /// looked up in the global scope in case it has been rebound.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// dict() /// dict()
/// dict(a=1, b=2) /// 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 /// 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. /// elements are unchanged. Wrap the iterable with `dict()`, `list()`, or `set()` instead.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// {a: b for a, b in iterable} /// {a: b for a, b in iterable}
/// [x for x 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, /// short-circuiting it may not improve performance. (It may even slightly regress performance,
/// though the difference will usually be small.) /// though the difference will usually be small.)
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// any([x.id for x in bar]) /// any([x.id for x in bar])
/// all([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}`, /// Prefer `dict.fromkeys(iterable)` over `{value: None for value in iterable}`,
/// as `dict.fromkeys` is more readable and efficient. /// as `dict.fromkeys` is more readable and efficient.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// {a: None for a in iterable} /// {a: None for a in iterable}
/// {a: 1 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 /// the listed functions within an additional `list()`, `set()`, `sorted()`, or
/// `tuple()` call. Doing so is redundant and can be confusing for readers. /// `tuple()` call. Doing so is redundant and can be confusing for readers.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// list(tuple(iterable)) /// list(tuple(iterable))
/// ``` /// ```

View file

@ -18,7 +18,7 @@ use super::helpers;
/// there are equivalent comprehensions for these types. Using a /// there are equivalent comprehensions for these types. Using a
/// comprehension is clearer and more idiomatic. /// comprehension is clearer and more idiomatic.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// dict((x, f(x)) for x in foo) /// 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 /// `list(x for x in foo)`, it's better to use `list(foo)` directly, since it's
/// even more direct. /// even more direct.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// list(f(x) for x in foo) /// list(f(x) for x in foo)
/// list(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 /// `set(x for x in foo)`, it's better to use `set(foo)` directly, since it's
/// even more direct. /// even more direct.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// set(f(x) for x in foo) /// set(f(x) for x in foo)
/// set(x for x in foo) /// set(x for x in foo)

View file

@ -16,7 +16,7 @@ use super::helpers;
/// ## Why is this bad? /// ## Why is this bad?
/// It is redundant to use a `list()` call around a list comprehension. /// It is redundant to use a `list()` call around a list comprehension.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// list([f(x) for x in foo]) /// 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()`, /// It's unnecessary to use a list comprehension inside a call to `dict()`,
/// since there is an equivalent comprehension for this type. /// since there is an equivalent comprehension for this type.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// dict([(x, f(x)) for x in foo]) /// 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()`, /// It's unnecessary to use a list comprehension inside a call to `set()`,
/// since there is an equivalent comprehension for this type. /// since there is an equivalent comprehension for this type.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// set([f(x) for x in foo]) /// 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's unnecessary to use a list or tuple literal within a call to `dict()`.
/// It can be rewritten as a dict literal (`{}`). /// It can be rewritten as a dict literal (`{}`).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// dict([(1, 2), (3, 4)]) /// dict([(1, 2), (3, 4)])
/// 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()`. /// 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. /// Instead, the expression can be rewritten as a set literal.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// set([1, 2]) /// set([1, 2])
/// 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 /// call, since the literal or comprehension syntax already returns a
/// dictionary. /// dictionary.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// dict({}) /// dict({})
/// dict({"a": 1}) /// 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 /// removed. Otherwise, if a tuple literal is passed in, then it should be
/// rewritten as a list literal. /// rewritten as a list literal.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// list([1, 2]) /// list([1, 2])
/// 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 /// calls. If a list comprehension is found, it should be rewritten as a
/// generator expression. /// generator expression.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// tuple([1, 2]) /// tuple([1, 2])
/// 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 /// - Instead of `dict(map(lambda v: (v, v ** 2), values))`, use
/// `{v: v ** 2 for v in values}`. /// `{v: v ** 2 for v in values}`.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// map(lambda x: x + 1, iterable) /// 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 /// into `reversed()`, `set()` or `sorted()` functions as they will change
/// the order of the elements again. /// the order of the elements again.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// sorted(iterable[::-1]) /// sorted(iterable[::-1])
/// set(iterable[::-1]) /// set(iterable[::-1])

View file

@ -27,7 +27,7 @@ use super::helpers;
/// 6. `def get_absolute_url()` /// 6. `def get_absolute_url()`
/// 7. Any custom methods /// 7. Any custom methods
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// from django.db import models /// 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. /// Checks for unannotated assignments in stub (`.pyi`) files.
/// ///
/// ## Why is this bad? /// ## 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 /// if the given suffix is not prefixed with a dot
/// or it is a single dot `"."`. /// or it is a single dot `"."`.
/// ///
/// ## Examples /// ## Example
/// ///
/// ```python /// ```python
/// path.with_suffix("py") /// 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., /// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getatime()`). /// `os.path.getatime()`).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import os /// 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., /// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getctime()`). /// `os.path.getctime()`).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import os /// 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., /// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getmtime()`). /// `os.path.getmtime()`).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import os /// 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., /// improve readability over the `os.path` module's counterparts (e.g.,
/// `os.path.getsize()`). /// `os.path.getsize()`).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import os /// import os
/// ///

View file

@ -17,7 +17,7 @@ use crate::importer::ImportRequest;
/// ///
/// Prefer newer APIs over deprecated ones. /// Prefer newer APIs over deprecated ones.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import numpy as np /// 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 /// Note, however, that `np.bool` and `np.long` were reintroduced in 2.0 with
/// different semantics, and are thus omitted from this rule. /// different semantics, and are thus omitted from this rule.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import numpy as np /// 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 /// See the documentation on [Random Sampling] and [NEP 19] for further
/// details. /// details.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import numpy as np /// 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 /// This rule flags all uses of removed members, along with automatic fixes for
/// any backwards-compatible replacements. /// any backwards-compatible replacements.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// import numpy as np /// 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 /// If a class definition doesn't have any bases, the parentheses are
/// unnecessary. /// unnecessary.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// class Foo(): /// 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 /// Omitting type arguments that match the default values can make the code
/// more concise and easier to read. /// more concise and easier to read.
/// ///
/// ## Examples /// ## Example
/// ///
/// ```python /// ```python
/// from collections.abc import Generator, AsyncGenerator /// 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 /// the use of `from_float` and `from_decimal` methods is unnecessary, and
/// should be avoided in favor of the more concise constructor syntax. /// should be avoided in favor of the more concise constructor syntax.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// Decimal.from_float(4.2) /// Decimal.from_float(4.2)
/// Decimal.from_float(float("inf")) /// 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 /// which may result in unexpected behavior (e.g., undefined variable
/// accesses). /// accesses).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// assert (x := 0) == 0 /// assert (x := 0) == 0
/// print(x) /// print(x)

View file

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

View file

@ -29,7 +29,7 @@ use crate::rules::ruff::rules::helpers::{
/// Attributes whose default arguments are `NewType` calls /// Attributes whose default arguments are `NewType` calls
/// where the original type is immutable are ignored. /// where the original type is immutable are ignored.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// from dataclasses import dataclass /// 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 /// Suppression comments that do not actually prevent formatting could cause unintended changes
/// when the formatter is run. /// when the formatter is run.
/// ///
/// ## Examples /// ## Example
/// In the following example, all suppression comments would cause /// In the following example, all suppression comments would cause
/// a rule violation. /// 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 /// If the default value is intended to be mutable, it must be annotated with
/// `typing.ClassVar`; otherwise, a `ValueError` will be raised. /// `typing.ClassVar`; otherwise, a `ValueError` will be raised.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// from dataclasses import dataclass /// 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, /// without having to check if the dictionary contains the relevant key,
/// returning `None` if the key is not present. /// returning `None` if the key is not present.
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// if "key" in dct and dct["key"]: /// if "key" in dct and dct["key"]:
/// ... /// ...

View file

@ -10,7 +10,7 @@ use ruff_text_size::Ranged;
/// ## Why is this bad? /// ## Why is this bad?
/// It's unnecessary to use an empty literal as a deque's iterable, since this is already the default behavior. /// It's unnecessary to use an empty literal as a deque's iterable, since this is already the default behavior.
/// ///
/// ## Examples /// ## Example
/// ///
/// ```python /// ```python
/// from collections import deque /// 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 /// contexts where that function may be called. In some cases, labeling a function `async` is
/// semantically meaningful (e.g. with the trio library). /// semantically meaningful (e.g. with the trio library).
/// ///
/// ## Examples /// ## Example
/// ```python /// ```python
/// async def foo(): /// async def foo():
/// bar() /// bar()