Format `PYI` examples in docs as `.pyi`-file snippets (#13116)

This commit is contained in:
Calum Young 2024-08-28 13:20:40 +01:00 committed by GitHub
parent cfafaa7637
commit 2e75cfbfe7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 125 additions and 148 deletions

View File

@ -27,14 +27,14 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// def __eq__(self, obj: typing.Any) -> bool: ... /// def __eq__(self, obj: typing.Any) -> bool: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// def __eq__(self, obj: object) -> bool: ... /// def __eq__(self, obj: object) -> bool: ...
/// ``` /// ```

View File

@ -34,19 +34,17 @@ use crate::registry::Rule;
/// ``` /// ```
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info > (3, 8): /// if sys.version_info > (3, 8): ...
/// ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info >= (3, 9): /// if sys.version_info >= (3, 9): ...
/// ...
/// ``` /// ```
#[violation] #[violation]
pub struct BadVersionInfoComparison; pub struct BadVersionInfoComparison;
@ -70,27 +68,23 @@ impl Violation for BadVersionInfoComparison {
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info < (3, 10): /// if sys.version_info < (3, 10):
///
/// def read_data(x, *, preserve_order=True): ... /// def read_data(x, *, preserve_order=True): ...
/// ///
/// else: /// else:
///
/// def read_data(x): ... /// def read_data(x): ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// if sys.version_info >= (3, 10): /// if sys.version_info >= (3, 10):
///
/// def read_data(x): ... /// def read_data(x): ...
/// ///
/// else: /// else:
///
/// def read_data(x, *, preserve_order=True): ... /// def read_data(x, *, preserve_order=True): ...
/// ``` /// ```
#[violation] #[violation]

View File

@ -21,17 +21,16 @@ use crate::checkers::ast::Checker;
/// precisely. /// precisely.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from collections import namedtuple /// from collections import namedtuple
/// ///
/// person = namedtuple("Person", ["name", "age"]) /// person = namedtuple("Person", ["name", "age"])
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import NamedTuple /// from typing import NamedTuple
/// ///
///
/// class Person(NamedTuple): /// class Person(NamedTuple):
/// name: str /// name: str
/// age: int /// age: int

View File

@ -20,27 +20,24 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// from typing import TypeAlias /// from typing import TypeAlias
/// ///
/// a = b = int /// a = b = int
/// ///
///
/// class Klass: ... /// class Klass: ...
/// ///
///
/// Klass.X: TypeAlias = int /// Klass.X: TypeAlias = int
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// from typing import TypeAlias /// from typing import TypeAlias
/// ///
/// a: TypeAlias = int /// a: TypeAlias = int
/// b: TypeAlias = int /// b: TypeAlias = int
/// ///
///
/// class Klass: /// class Klass:
/// X: TypeAlias = int /// X: TypeAlias = int
/// ``` /// ```

View File

@ -16,19 +16,17 @@ use crate::checkers::ast::Checker;
/// analyze your code. /// analyze your code.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if (3, 10) <= sys.version_info < (3, 12): /// if (3, 10) <= sys.version_info < (3, 12): ...
/// ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info >= (3, 10) and sys.version_info < (3, 12): /// if sys.version_info >= (3, 10) and sys.version_info < (3, 12): ...
/// ...
/// ``` /// ```
/// ///
/// ## References /// ## References

View File

@ -25,27 +25,22 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... /// def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ...
///
/// def foo(self: _S, arg: bytes) -> _S: ... /// def foo(self: _S, arg: bytes) -> _S: ...
///
/// @classmethod /// @classmethod
/// def bar(cls: type[_S], arg: int) -> _S: ... /// def bar(cls: type[_S], arg: int) -> _S: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// from typing import Self /// from typing import Self
/// ///
///
/// class Foo: /// class Foo:
/// def __new__(cls, *args: str, **kwargs: int) -> Self: ... /// def __new__(cls, *args: str, **kwargs: int) -> Self: ...
///
/// def foo(self, arg: bytes) -> Self: ... /// def foo(self, arg: bytes) -> Self: ...
///
/// @classmethod /// @classmethod
/// def bar(cls, arg: int) -> Self: ... /// def bar(cls, arg: int) -> Self: ...
/// ``` /// ```

View File

@ -15,7 +15,7 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def func(param: int) -> str: /// def func(param: int) -> str:
/// """This is a docstring.""" /// """This is a docstring."""
/// ... /// ...
@ -23,7 +23,7 @@ use crate::checkers::ast::Checker;
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def func(param: int) -> str: ... /// def func(param: int) -> str: ...
/// ``` /// ```
#[violation] #[violation]

View File

@ -15,14 +15,14 @@ use crate::fix;
/// is redundant. /// is redundant.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// ... /// ...
/// value: int /// value: int
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// value: int /// value: int
/// ``` /// ```

View File

@ -24,10 +24,9 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// from types import TracebackType /// from types import TracebackType
/// ///
///
/// class Foo: /// class Foo:
/// def __exit__( /// def __exit__(
/// self, typ: BaseException, exc: BaseException, tb: TracebackType /// self, typ: BaseException, exc: BaseException, tb: TracebackType
@ -36,10 +35,9 @@ use crate::checkers::ast::Checker;
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// from types import TracebackType /// from types import TracebackType
/// ///
///
/// class Foo: /// class Foo:
/// def __exit__( /// def __exit__(
/// self, /// self,

View File

@ -22,14 +22,14 @@ use crate::settings::types::PythonVersion::Py311;
/// members). /// members).
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from typing import NoReturn /// from typing import NoReturn
/// ///
/// def foo(x: NoReturn): ... /// def foo(x: NoReturn): ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import Never /// from typing import Never
/// ///
/// def foo(x: Never): ... /// def foo(x: Never): ...

View File

@ -15,13 +15,13 @@ use crate::checkers::ast::Checker;
/// for this purpose. /// for this purpose.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// def double(x: int) -> int: /// def double(x: int) -> int:
/// return x * 2 /// return x * 2
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// def double(x: int) -> int: ... /// def double(x: int) -> int: ...
/// ``` /// ```
/// ///

View File

@ -51,30 +51,23 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// def __new__(cls, *args: Any, **kwargs: Any) -> Foo: ... /// def __new__(cls, *args: Any, **kwargs: Any) -> Foo: ...
///
/// def __enter__(self) -> Foo: ... /// def __enter__(self) -> Foo: ...
///
/// async def __aenter__(self) -> Foo: ... /// async def __aenter__(self) -> Foo: ...
///
/// def __iadd__(self, other: Foo) -> Foo: ... /// def __iadd__(self, other: Foo) -> Foo: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// from typing_extensions import Self /// from typing_extensions import Self
/// ///
///
/// class Foo: /// class Foo:
/// def __new__(cls, *args: Any, **kwargs: Any) -> Self: ... /// def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
///
/// def __enter__(self) -> Self: ... /// def __enter__(self) -> Self: ...
///
/// async def __aenter__(self) -> Self: ... /// async def __aenter__(self) -> Self: ...
///
/// def __iadd__(self, other: Foo) -> Self: ... /// def __iadd__(self, other: Foo) -> Self: ...
/// ``` /// ```
/// ## References /// ## References

View File

@ -20,13 +20,13 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def foo(arg: int = 693568516352839939918568862861217771399698285293568) -> None: ... /// def foo(arg: int = 693568516352839939918568862861217771399698285293568) -> None: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def foo(arg: int = ...) -> None: ... /// def foo(arg: int = ...) -> None: ...
/// ``` /// ```
#[violation] #[violation]

View File

@ -15,14 +15,14 @@ use crate::fix;
/// stubs. /// stubs.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// class MyClass: /// class MyClass:
/// x: int /// x: int
/// pass /// pass
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// class MyClass: /// class MyClass:
/// x: int /// x: int
/// ``` /// ```

View File

@ -13,12 +13,12 @@ use crate::checkers::ast::Checker;
/// in stub files. /// in stub files.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// def foo(bar: int) -> list[int]: pass /// def foo(bar: int) -> list[int]: pass
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// def foo(bar: int) -> list[int]: ... /// def foo(bar: int) -> list[int]: ...
/// ``` /// ```
/// ///

View File

@ -17,13 +17,13 @@ use crate::settings::types::PythonVersion;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def foo(__x: int) -> None: ... /// def foo(__x: int) -> None: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def foo(x: int, /) -> None: ... /// def foo(x: int, /) -> None: ...
/// ``` /// ```
/// ///

View File

@ -33,14 +33,14 @@ impl fmt::Display for VarKind {
/// internal to the stub. /// internal to the stub.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from typing import TypeVar /// from typing import TypeVar
/// ///
/// T = TypeVar("T") /// T = TypeVar("T")
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import TypeVar /// from typing import TypeVar
/// ///
/// _T = TypeVar("_T") /// _T = TypeVar("_T")

View File

@ -16,13 +16,13 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def function() -> "int": ... /// def function() -> "int": ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def function() -> int: ... /// def function() -> int: ...
/// ``` /// ```
/// ///

View File

@ -16,13 +16,13 @@ use crate::fix::snippet::SourceCodeSnippet;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// x: Final[Literal[42]] /// x: Final[Literal[42]]
/// y: Final[Literal[42]] = 42 /// y: Final[Literal[42]] = 42
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// x: Final = 42 /// x: Final = 42
/// y: Final = 42 /// y: Final = 42
/// ``` /// ```

View File

@ -24,14 +24,14 @@ use crate::fix::snippet::SourceCodeSnippet;
/// supertypes of `"A"` and `1` respectively. /// supertypes of `"A"` and `1` respectively.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from typing import Literal /// from typing import Literal
/// ///
/// x: Literal["A", b"B"] | str /// x: Literal["A", b"B"] | str
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import Literal /// from typing import Literal
/// ///
/// x: Literal[b"B"] | str /// x: Literal[b"B"] | str

View File

@ -27,13 +27,13 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def foo(x: float | int | str) -> None: ... /// def foo(x: float | int | str) -> None: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def foo(x: float | str) -> None: ... /// def foo(x: float | str) -> None: ...
/// ``` /// ```
/// ///

View File

@ -31,13 +31,13 @@ use crate::settings::types::PythonVersion;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def foo(arg: list[int] = list(range(10_000))) -> None: ... /// def foo(arg: list[int] = list(range(10_000))) -> None: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def foo(arg: list[int] = ...) -> None: ... /// def foo(arg: list[int] = ...) -> None: ...
/// ``` /// ```
/// ///
@ -77,13 +77,13 @@ impl AlwaysFixableViolation for TypedArgumentDefaultInStub {
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def foo(arg=[]) -> None: ... /// def foo(arg=[]) -> None: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def foo(arg=...) -> None: ... /// def foo(arg=...) -> None: ...
/// ``` /// ```
/// ///
@ -122,12 +122,12 @@ impl AlwaysFixableViolation for ArgumentDefaultInStub {
/// or varies according to the current platform or Python version. /// or varies according to the current platform or Python version.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// foo: str = "..." /// foo: str = "..."
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// foo: str = ... /// foo: str = ...
/// ``` /// ```
/// ///
@ -176,12 +176,12 @@ impl Violation for UnannotatedAssignmentInStub {
/// runtime counterparts. /// runtime counterparts.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// __all__: list[str] /// __all__: list[str]
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// __all__: list[str] = ["foo", "bar"] /// __all__: list[str] = ["foo", "bar"]
/// ``` /// ```
#[violation] #[violation]
@ -210,12 +210,12 @@ impl Violation for UnassignedSpecialVariableInStub {
/// to a normal variable assignment. /// to a normal variable assignment.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// Vector = list[float] /// Vector = list[float]
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import TypeAlias /// from typing import TypeAlias
/// ///
/// Vector: TypeAlias = list[float] /// Vector: TypeAlias = list[float]

View File

@ -19,7 +19,7 @@ use crate::fix::edits::delete_stmt;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// class Foo: /// class Foo:
/// def __repr__(self) -> str: ... /// def __repr__(self) -> str: ...
/// ``` /// ```

View File

@ -23,13 +23,13 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def foo(arg: str = "51 character stringgggggggggggggggggggggggggggggggg") -> None: ... /// def foo(arg: str = "51 character stringgggggggggggggggggggggggggggggggg") -> None: ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def foo(arg: str = ...) -> None: ... /// def foo(arg: str = ...) -> None: ...
/// ``` /// ```
#[violation] #[violation]

View File

@ -16,7 +16,7 @@ use crate::checkers::ast::Checker;
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// def function(): /// def function():
/// x = 1 /// x = 1
/// y = 2 /// y = 2
@ -25,7 +25,7 @@ use crate::checkers::ast::Checker;
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// def function(): ... /// def function(): ...
/// ``` /// ```
#[violation] #[violation]

View File

@ -13,12 +13,12 @@ use crate::checkers::ast::Checker;
/// to distinguish them from other variables. /// to distinguish them from other variables.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// type_alias_name: TypeAlias = int /// type_alias_name: TypeAlias = int
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// TypeAliasName: TypeAlias = int /// TypeAliasName: TypeAlias = int
/// ``` /// ```
#[violation] #[violation]
@ -45,14 +45,14 @@ impl Violation for SnakeCaseTypeAlias {
/// be avoided. /// be avoided.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from typing import TypeAlias /// from typing import TypeAlias
/// ///
/// _MyTypeT: TypeAlias = int /// _MyTypeT: TypeAlias = int
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import TypeAlias /// from typing import TypeAlias
/// ///
/// _MyType: TypeAlias = int /// _MyType: TypeAlias = int

View File

@ -16,12 +16,12 @@ use ruff_macros::{derive_message_formats, violation};
/// stub files are not executed at runtime. The one exception is `# type: ignore`. /// stub files are not executed at runtime. The one exception is `# type: ignore`.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// x = 1 # type: int /// x = 1 # type: int
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// x: int = 1 /// x: int = 1
/// ``` /// ```
#[violation] #[violation]

View File

@ -21,12 +21,12 @@ use crate::renamer::Renamer;
/// `set` builtin. /// `set` builtin.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from collections.abc import Set /// from collections.abc import Set
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from collections.abc import Set as AbstractSet /// from collections.abc import Set as AbstractSet
/// ``` /// ```
/// ///

View File

@ -15,14 +15,14 @@ use crate::checkers::ast::Checker;
/// `Literal["foo"] | Literal[42]`, but is clearer and more concise. /// `Literal["foo"] | Literal[42]`, but is clearer and more concise.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// from typing import Literal /// from typing import Literal
/// ///
/// field: Literal[1] | Literal[2] | str /// field: Literal[1] | Literal[2] | str
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// from typing import Literal /// from typing import Literal
/// ///
/// field: Literal[1, 2] | str /// field: Literal[1, 2] | str

View File

@ -17,12 +17,12 @@ use crate::checkers::ast::Checker;
/// annotation, but is cleaner and more concise. /// annotation, but is cleaner and more concise.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// field: type[int] | type[float] | str /// field: type[int] | type[float] | str
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// field: type[int | float] | str /// field: type[int | float] | str
/// ``` /// ```
#[violation] #[violation]

View File

@ -20,7 +20,7 @@ use crate::registry::Rule;
/// `if sys.platform == "linux"`. /// `if sys.platform == "linux"`.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// if sys.platform.startswith("linux"): /// if sys.platform.startswith("linux"):
/// # Linux specific definitions /// # Linux specific definitions
/// ... /// ...
@ -30,7 +30,7 @@ use crate::registry::Rule;
/// ``` /// ```
/// ///
/// Instead, use a simple string comparison, such as `==` or `!=`: /// Instead, use a simple string comparison, such as `==` or `!=`:
/// ```python /// ```pyi
/// if sys.platform == "linux": /// if sys.platform == "linux":
/// # Linux specific definitions /// # Linux specific definitions
/// ... /// ...
@ -64,15 +64,13 @@ impl Violation for UnrecognizedPlatformCheck {
/// The list of known platforms is: "linux", "win32", "cygwin", "darwin". /// The list of known platforms is: "linux", "win32", "cygwin", "darwin".
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// if sys.platform == "linus": /// if sys.platform == "linus": ...
/// ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// if sys.platform == "linux": /// if sys.platform == "linux": ...
/// ...
/// ``` /// ```
/// ///
/// ## References /// ## References

View File

@ -17,19 +17,17 @@ use crate::registry::Rule;
/// For example, comparing against a string can lead to unexpected behavior. /// For example, comparing against a string can lead to unexpected behavior.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info[0] == "2": /// if sys.version_info[0] == "2": ...
/// ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info[0] == 2: /// if sys.version_info[0] == 2: ...
/// ...
/// ``` /// ```
/// ///
/// ## References /// ## References
@ -58,19 +56,17 @@ impl Violation for UnrecognizedVersionInfoCheck {
/// and minor versions. /// and minor versions.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info >= (3, 4, 3): /// if sys.version_info >= (3, 4, 3): ...
/// ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info >= (3, 4): /// if sys.version_info >= (3, 4): ...
/// ...
/// ``` /// ```
/// ///
/// ## References /// ## References
@ -96,19 +92,17 @@ impl Violation for PatchVersionComparison {
/// behavior. /// behavior.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info[:2] == (3,): /// if sys.version_info[:2] == (3,): ...
/// ...
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// if sys.version_info[0] == 3: /// if sys.version_info[0] == 3: ...
/// ...
/// ``` /// ```
/// ///
/// ## References /// ## References

View File

@ -16,7 +16,7 @@ use crate::checkers::ast::Checker;
/// `__all__`, which is known to be supported by all major type checkers. /// `__all__`, which is known to be supported by all major type checkers.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// __all__ = ["A", "B"] /// __all__ = ["A", "B"]
@ -29,7 +29,7 @@ use crate::checkers::ast::Checker;
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```pyi
/// import sys /// import sys
/// ///
/// __all__ = ["A"] /// __all__ = ["A"]

View File

@ -16,7 +16,7 @@ use crate::checkers::ast::Checker;
/// should either be used, made public, or removed to avoid confusion. /// should either be used, made public, or removed to avoid confusion.
/// ///
/// ## Example /// ## Example
/// ```python /// ```pyi
/// import typing /// import typing
/// import typing_extensions /// import typing_extensions
/// ///
@ -50,24 +50,21 @@ impl Violation for UnusedPrivateTypeVar {
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// import typing /// import typing
/// ///
///
/// class _PrivateProtocol(typing.Protocol): /// class _PrivateProtocol(typing.Protocol):
/// foo: int /// foo: int
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// import typing /// import typing
/// ///
///
/// class _PrivateProtocol(typing.Protocol): /// class _PrivateProtocol(typing.Protocol):
/// foo: int /// foo: int
/// ///
///
/// def func(arg: _PrivateProtocol) -> None: ... /// def func(arg: _PrivateProtocol) -> None: ...
/// ``` /// ```
#[violation] #[violation]
@ -93,7 +90,7 @@ impl Violation for UnusedPrivateProtocol {
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// import typing /// import typing
/// ///
/// _UnusedTypeAlias: typing.TypeAlias = int /// _UnusedTypeAlias: typing.TypeAlias = int
@ -101,12 +98,11 @@ impl Violation for UnusedPrivateProtocol {
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// import typing /// import typing
/// ///
/// _UsedTypeAlias: typing.TypeAlias = int /// _UsedTypeAlias: typing.TypeAlias = int
/// ///
///
/// def func(arg: _UsedTypeAlias) -> _UsedTypeAlias: ... /// def func(arg: _UsedTypeAlias) -> _UsedTypeAlias: ...
/// ``` /// ```
#[violation] #[violation]
@ -132,24 +128,21 @@ impl Violation for UnusedPrivateTypeAlias {
/// ///
/// ## Example /// ## Example
/// ///
/// ```python /// ```pyi
/// import typing /// import typing
/// ///
///
/// class _UnusedPrivateTypedDict(typing.TypedDict): /// class _UnusedPrivateTypedDict(typing.TypedDict):
/// foo: list[int] /// foo: list[int]
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ///
/// ```python /// ```pyi
/// import typing /// import typing
/// ///
///
/// class _UsedPrivateTypedDict(typing.TypedDict): /// class _UsedPrivateTypedDict(typing.TypedDict):
/// foo: set[str] /// foo: set[str]
/// ///
///
/// def func(arg: _UsedPrivateTypedDict) -> _UsedPrivateTypedDict: ... /// def func(arg: _UsedPrivateTypedDict) -> _UsedPrivateTypedDict: ...
/// ``` /// ```
#[violation] #[violation]

View File

@ -6,3 +6,6 @@ mkdocs-redirects==1.2.1
mdformat==0.7.17 mdformat==0.7.17
mdformat-mkdocs==3.0.0 mdformat-mkdocs==3.0.0
mdformat-admon==2.0.6 mdformat-admon==2.0.6
# Using a commit from pygments main branch so we get
# https://github.com/pygments/pygments/pull/2773 before it's been released
pygments @ git+https://github.com/pygments/pygments.git@67b460fdde6d9a00342b5102b37b3a8399f0e8ef

View File

@ -6,3 +6,6 @@ mkdocs-redirects==1.2.1
mdformat==0.7.17 mdformat==0.7.17
mdformat-mkdocs==3.0.0 mdformat-mkdocs==3.0.0
mdformat-admon==2.0.6 mdformat-admon==2.0.6
# Using a commit from pygments main branch so we get
# https://github.com/pygments/pygments/pull/2773 before it's been released
pygments @ git+https://github.com/pygments/pygments.git@67b460fdde6d9a00342b5102b37b3a8399f0e8ef

View File

@ -10,13 +10,13 @@ import subprocess
import textwrap import textwrap
from pathlib import Path from pathlib import Path
from re import Match from re import Match
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Literal
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import Sequence from collections.abc import Sequence
SNIPPED_RE = re.compile( SNIPPED_RE = re.compile(
r"(?P<before>^(?P<indent> *)```\s*python\n)" r"(?P<before>^(?P<indent> *)```(?:\s*(?P<language>\w+))?\n)"
r"(?P<code>.*?)" r"(?P<code>.*?)"
r"(?P<after>^(?P=indent)```\s*$)", r"(?P<after>^(?P=indent)```\s*$)",
re.DOTALL | re.MULTILINE, re.DOTALL | re.MULTILINE,
@ -120,12 +120,12 @@ class InvalidInput(ValueError):
"""Raised when ruff fails to parse file.""" """Raised when ruff fails to parse file."""
def format_str(code: str) -> str: def format_str(code: str, extension: Literal["py", "pyi"]) -> str:
"""Format a code block with ruff by writing to a temporary file.""" """Format a code block with ruff by writing to a temporary file."""
# Run ruff to format the tmp file # Run ruff to format the tmp file
try: try:
completed_process = subprocess.run( completed_process = subprocess.run(
["ruff", "format", "-"], ["ruff", "format", "--stdin-filename", f"file.{extension}", "-"],
check=True, check=True,
capture_output=True, capture_output=True,
text=True, text=True,
@ -149,9 +149,21 @@ def format_contents(src: str) -> tuple[str, Sequence[CodeBlockError]]:
errors: list[CodeBlockError] = [] errors: list[CodeBlockError] = []
def _snipped_match(match: Match[str]) -> str: def _snipped_match(match: Match[str]) -> str:
language = match["language"]
extension: Literal["py", "pyi"]
match language:
case "python":
extension = "py"
case "pyi":
extension = "pyi"
case _:
# We are only interested in checking the formatting of py or pyi code
# blocks so we can return early if the language is not one of these.
return f'{match["before"]}{match["code"]}{match["after"]}'
code = textwrap.dedent(match["code"]) code = textwrap.dedent(match["code"])
try: try:
code = format_str(code) code = format_str(code, extension)
except InvalidInput as e: except InvalidInput as e:
errors.append(CodeBlockError(e)) errors.append(CodeBlockError(e))
except NotImplementedError as e: except NotImplementedError as e: