mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-21 02:50:31 +00:00
[ruff-0.8] Spruce up docs for newly stabilised rules (#14466)
## Summary - Expand some docs where they're unclear about the motivation, or assume some knowledge that hasn't been introduced yet - Add more links to external docs - Rename PYI063 from `PrePep570PositionalArgument` to `Pep484StylePositionalOnlyParameter` - Rename the file `parenthesize_logical_operators.rs` to `parenthesize_chained_operators.rs`, since the rule is called `ParenthesizeChainedOperators`, not `ParenthesizeLogicalOperators` ## Test Plan `cargo test`
This commit is contained in:
parent
aa7ac2ce0f
commit
cef12f4925
17 changed files with 124 additions and 101 deletions
|
@ -180,8 +180,8 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
if checker.enabled(Rule::RedundantNumericUnion) {
|
||||
flake8_pyi::rules::redundant_numeric_union(checker, parameters);
|
||||
}
|
||||
if checker.enabled(Rule::PrePep570PositionalArgument) {
|
||||
flake8_pyi::rules::pre_pep570_positional_argument(checker, function_def);
|
||||
if checker.enabled(Rule::Pep484StylePositionalOnlyParameter) {
|
||||
flake8_pyi::rules::pep_484_positional_parameter(checker, function_def);
|
||||
}
|
||||
if checker.enabled(Rule::DunderFunctionName) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::dunder_function_name(
|
||||
|
|
|
@ -791,7 +791,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Flake8Pyi, "059") => (RuleGroup::Preview, rules::flake8_pyi::rules::GenericNotLastBaseClass),
|
||||
(Flake8Pyi, "061") => (RuleGroup::Preview, rules::flake8_pyi::rules::RedundantNoneLiteral),
|
||||
(Flake8Pyi, "062") => (RuleGroup::Stable, rules::flake8_pyi::rules::DuplicateLiteralMember),
|
||||
(Flake8Pyi, "063") => (RuleGroup::Stable, rules::flake8_pyi::rules::PrePep570PositionalArgument),
|
||||
(Flake8Pyi, "063") => (RuleGroup::Stable, rules::flake8_pyi::rules::Pep484StylePositionalOnlyParameter),
|
||||
(Flake8Pyi, "064") => (RuleGroup::Stable, rules::flake8_pyi::rules::RedundantFinalLiteral),
|
||||
(Flake8Pyi, "066") => (RuleGroup::Stable, rules::flake8_pyi::rules::BadVersionInfoOrder),
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@ use crate::rules::fastapi::rules::is_fastapi_route;
|
|||
use crate::settings::types::PythonVersion;
|
||||
|
||||
/// ## What it does
|
||||
/// Identifies FastAPI routes with deprecated uses of `Depends`.
|
||||
/// Identifies FastAPI routes with deprecated uses of `Depends` or similar.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// The FastAPI documentation recommends the use of `Annotated` for defining
|
||||
/// route dependencies and parameters, rather than using `Depends` directly
|
||||
/// with a default value.
|
||||
///
|
||||
/// This approach is also suggested for various route parameters, including Body and Cookie, as it helps ensure consistency and clarity in defining dependencies and parameters.
|
||||
/// The [FastAPI documentation] recommends the use of [`typing.Annotated`] for
|
||||
/// defining route dependencies and parameters, rather than using `Depends`,
|
||||
/// `Query` or similar as a default value for a parameter. Using this approach
|
||||
/// everywhere helps ensure consistency and clarity in defining dependencies
|
||||
/// and parameters.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
|
@ -55,7 +55,9 @@ use crate::settings::types::PythonVersion;
|
|||
/// async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
|
||||
/// return commons
|
||||
/// ```
|
||||
|
||||
///
|
||||
/// [fastAPI documentation]: https://fastapi.tiangolo.com/tutorial/query-params-str-validations/?h=annotated#advantages-of-annotated
|
||||
/// [typing.Annotated]: https://docs.python.org/3/library/typing.html#typing.Annotated
|
||||
#[violation]
|
||||
pub struct FastApiNonAnnotatedDependency;
|
||||
|
||||
|
@ -72,7 +74,7 @@ impl Violation for FastApiNonAnnotatedDependency {
|
|||
}
|
||||
}
|
||||
|
||||
/// RUF103
|
||||
/// FAST002
|
||||
pub(crate) fn fastapi_non_annotated_dependency(
|
||||
checker: &mut Checker,
|
||||
function_def: &ast::StmtFunctionDef,
|
||||
|
|
|
@ -73,7 +73,7 @@ impl AlwaysFixableViolation for FastApiRedundantResponseModel {
|
|||
}
|
||||
}
|
||||
|
||||
/// RUF102
|
||||
/// FAST001
|
||||
pub(crate) fn fastapi_redundant_response_model(
|
||||
checker: &mut Checker,
|
||||
function_def: &StmtFunctionDef,
|
||||
|
|
|
@ -19,9 +19,9 @@ use crate::checkers::ast::Checker;
|
|||
/// the `ContextVar`. If the object is modified, those modifications will persist
|
||||
/// across calls, which can lead to unexpected behavior.
|
||||
///
|
||||
/// Instead, prefer to use immutable data structures; or, take `None` as a
|
||||
/// default, and initialize a new mutable object inside for each call using the
|
||||
/// `.set()` method.
|
||||
/// Instead, prefer to use immutable data structures. Alternatively, take
|
||||
/// `None` as a default, and initialize a new mutable object inside for each
|
||||
/// call using the `.set()` method.
|
||||
///
|
||||
/// Types outside the standard library can be marked as immutable with the
|
||||
/// [`lint.flake8-bugbear.extend-immutable-calls`] configuration option.
|
||||
|
|
|
@ -66,8 +66,8 @@ mod tests {
|
|||
#[test_case(Rule::PatchVersionComparison, Path::new("PYI004.pyi"))]
|
||||
#[test_case(Rule::QuotedAnnotationInStub, Path::new("PYI020.py"))]
|
||||
#[test_case(Rule::QuotedAnnotationInStub, Path::new("PYI020.pyi"))]
|
||||
#[test_case(Rule::PrePep570PositionalArgument, Path::new("PYI063.py"))]
|
||||
#[test_case(Rule::PrePep570PositionalArgument, Path::new("PYI063.pyi"))]
|
||||
#[test_case(Rule::Pep484StylePositionalOnlyParameter, Path::new("PYI063.py"))]
|
||||
#[test_case(Rule::Pep484StylePositionalOnlyParameter, Path::new("PYI063.pyi"))]
|
||||
#[test_case(Rule::RedundantFinalLiteral, Path::new("PYI064.py"))]
|
||||
#[test_case(Rule::RedundantFinalLiteral, Path::new("PYI064.pyi"))]
|
||||
#[test_case(Rule::RedundantLiteralUnion, Path::new("PYI051.py"))]
|
||||
|
|
|
@ -16,8 +16,9 @@ use crate::registry::Rule;
|
|||
/// Comparing `sys.version_info` with `==` or `<=` has unexpected behavior
|
||||
/// and can lead to bugs.
|
||||
///
|
||||
/// For example, `sys.version_info > (3, 8)` will also match `3.8.10`,
|
||||
/// while `sys.version_info <= (3, 8)` will _not_ match `3.8.10`:
|
||||
/// For example, `sys.version_info > (3, 8, 1)` will resolve to `True` if your
|
||||
/// Python version is 3.8.1; meanwhile, `sys.version_info <= (3, 8)` will _not_
|
||||
/// resolve to `True` if your Python version is 3.8.10:
|
||||
///
|
||||
/// ```python
|
||||
/// >>> import sys
|
||||
|
@ -61,16 +62,20 @@ impl Violation for BadVersionInfoComparison {
|
|||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for if-else statements with `sys.version_info` comparisons that use
|
||||
/// `<` comparators.
|
||||
/// Checks for code that branches on `sys.version_info` comparisons where
|
||||
/// branches corresponding to older Python versions come before branches
|
||||
/// corresponding to newer Python versions.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// As a convention, branches that correspond to newer Python versions should
|
||||
/// come first when using `sys.version_info` comparisons. This makes it easier
|
||||
/// to understand the desired behavior, which typically corresponds to the
|
||||
/// latest Python versions.
|
||||
/// come first. This makes it easier to understand the desired behavior, which
|
||||
/// typically corresponds to the latest Python versions.
|
||||
///
|
||||
/// In [preview], this rule will also flag non-stub files.
|
||||
/// This rule enforces the convention by checking for `if` tests that compare
|
||||
/// `sys.version_info` with `<` rather than `>=`.
|
||||
///
|
||||
/// By default, this rule only applies to stub files.
|
||||
/// In [preview], it will also flag this anti-pattern in non-stub files.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
|
@ -101,7 +106,7 @@ pub struct BadVersionInfoOrder;
|
|||
impl Violation for BadVersionInfoOrder {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"Use `>=` when using `if`-`else` with `sys.version_info` comparisons".to_string()
|
||||
"Put branches for newer Python versions first when branching on `sys.version_info` comparisons".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,19 @@ use crate::checkers::ast::Checker;
|
|||
use crate::settings::types::PythonVersion;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for the presence of [PEP 484]-style positional-only arguments.
|
||||
/// Checks for the presence of [PEP 484]-style positional-only parameters.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Historically, [PEP 484] recommended prefixing positional-only arguments
|
||||
/// with a double underscore (`__`). However, [PEP 570] introduced a dedicated
|
||||
/// syntax for positional-only arguments, which should be preferred.
|
||||
/// Historically, [PEP 484] recommended prefixing parameter names with double
|
||||
/// underscores (`__`) to indicate to a type checker that they were
|
||||
/// positional-only. However, [PEP 570] (introduced in Python 3.8) introduced
|
||||
/// dedicated syntax for positional-only arguments. If a forward slash (`/`) is
|
||||
/// present in a function signature on Python 3.8+, all parameters prior to the
|
||||
/// slash are interpreted as positional-only.
|
||||
///
|
||||
/// The new syntax should be preferred as it is more widely used, more concise
|
||||
/// and more readable. It is also respected by Python at runtime, whereas the
|
||||
/// old-style syntax was only understood by type checkers.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
|
@ -33,12 +40,12 @@ use crate::settings::types::PythonVersion;
|
|||
/// [PEP 484]: https://peps.python.org/pep-0484/#positional-only-arguments
|
||||
/// [PEP 570]: https://peps.python.org/pep-0570
|
||||
#[violation]
|
||||
pub struct PrePep570PositionalArgument;
|
||||
pub struct Pep484StylePositionalOnlyParameter;
|
||||
|
||||
impl Violation for PrePep570PositionalArgument {
|
||||
impl Violation for Pep484StylePositionalOnlyParameter {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"Use PEP 570 syntax for positional-only arguments".to_string()
|
||||
"Use PEP 570 syntax for positional-only parameters".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
|
@ -47,7 +54,7 @@ impl Violation for PrePep570PositionalArgument {
|
|||
}
|
||||
|
||||
/// PYI063
|
||||
pub(crate) fn pre_pep570_positional_argument(
|
||||
pub(crate) fn pep_484_positional_parameter(
|
||||
checker: &mut Checker,
|
||||
function_def: &ast::StmtFunctionDef,
|
||||
) {
|
||||
|
@ -82,18 +89,18 @@ pub(crate) fn pre_pep570_positional_argument(
|
|||
));
|
||||
|
||||
if let Some(arg) = function_def.parameters.args.get(skip) {
|
||||
if is_pre_pep570_positional_only(arg) {
|
||||
if is_old_style_positional_only(arg) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
PrePep570PositionalArgument,
|
||||
Pep484StylePositionalOnlyParameter,
|
||||
arg.identifier(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the [`ParameterWithDefault`] is an old-style positional-only argument (i.e.,
|
||||
/// Returns `true` if the [`ParameterWithDefault`] is an old-style positional-only parameter (i.e.,
|
||||
/// its name starts with `__` and does not end with `__`).
|
||||
fn is_pre_pep570_positional_only(arg: &ParameterWithDefault) -> bool {
|
||||
fn is_old_style_positional_only(arg: &ParameterWithDefault) -> bool {
|
||||
let arg_name = &arg.parameter.name;
|
||||
arg_name.starts_with("__") && !arg_name.ends_with("__")
|
||||
}
|
||||
|
|
|
@ -11,18 +11,25 @@ use crate::Locator;
|
|||
/// Checks for redundant `Final[Literal[...]]` annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// A `Final[Literal[...]]` annotation can be replaced with `Final`; the literal
|
||||
/// use is unnecessary.
|
||||
/// All constant variables annotated as `Final` are understood as implicitly
|
||||
/// having `Literal` types by a type checker. As such, a `Final[Literal[...]]`
|
||||
/// annotation can often be replaced with a bare `Final`, annotation, which
|
||||
/// will have the same meaning to the type checker while being more concise and
|
||||
/// more readable.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```pyi
|
||||
/// from typing import Final, Literal
|
||||
///
|
||||
/// x: Final[Literal[42]]
|
||||
/// y: Final[Literal[42]] = 42
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```pyi
|
||||
/// from typing import Final, Literal
|
||||
///
|
||||
/// x: Final = 42
|
||||
/// y: Final = 42
|
||||
/// ```
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
PYI063.py:6:9: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:6:9: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
4 | from typing import Self
|
||||
5 |
|
||||
|
@ -13,7 +12,7 @@ PYI063.py:6:9: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:7:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:7:14: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
6 | def bad(__x: int) -> None: ... # PYI063
|
||||
7 | def also_bad(__x: int, __y: str) -> None: ... # PYI063
|
||||
|
@ -22,7 +21,7 @@ PYI063.py:7:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:8:15: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:8:15: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
6 | def bad(__x: int) -> None: ... # PYI063
|
||||
7 | def also_bad(__x: int, __y: str) -> None: ... # PYI063
|
||||
|
@ -33,7 +32,7 @@ PYI063.py:8:15: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:24:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:24:14: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
22 | def bad(__self) -> None: ... # PYI063
|
||||
23 | @staticmethod
|
||||
|
@ -44,7 +43,7 @@ PYI063.py:24:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:25:22: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:25:22: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
23 | @staticmethod
|
||||
24 | def bad2(__self) -> None: ... # PYI063
|
||||
|
@ -55,7 +54,7 @@ PYI063.py:25:22: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:26:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:26:25: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
24 | def bad2(__self) -> None: ... # PYI063
|
||||
25 | def bad3(__self, __x: int) -> None: ... # PYI063
|
||||
|
@ -66,7 +65,7 @@ PYI063.py:26:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:28:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:28:25: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
26 | def still_bad(self, __x_: int) -> None: ... # PYI063
|
||||
27 | @staticmethod
|
||||
|
@ -77,7 +76,7 @@ PYI063.py:28:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:30:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:30:23: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
28 | def this_is_bad_too(__x: int) -> None: ... # PYI063
|
||||
29 | @classmethod
|
||||
|
@ -88,7 +87,7 @@ PYI063.py:30:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:52:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:52:23: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
50 | class Metaclass(type):
|
||||
51 | @classmethod
|
||||
|
@ -99,7 +98,7 @@ PYI063.py:52:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.py:56:26: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.py:56:26: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
54 | class Metaclass2(type):
|
||||
55 | @classmethod
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
PYI063.pyi:6:9: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:6:9: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
4 | from typing import Self
|
||||
5 |
|
||||
|
@ -13,7 +12,7 @@ PYI063.pyi:6:9: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:7:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:7:14: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
6 | def bad(__x: int) -> None: ... # PYI063
|
||||
7 | def also_bad(__x: int, __y: str) -> None: ... # PYI063
|
||||
|
@ -22,7 +21,7 @@ PYI063.pyi:7:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:8:15: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:8:15: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
6 | def bad(__x: int) -> None: ... # PYI063
|
||||
7 | def also_bad(__x: int, __y: str) -> None: ... # PYI063
|
||||
|
@ -33,7 +32,7 @@ PYI063.pyi:8:15: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:24:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:24:14: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
22 | def bad(__self) -> None: ... # PYI063
|
||||
23 | @staticmethod
|
||||
|
@ -44,7 +43,7 @@ PYI063.pyi:24:14: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:25:22: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:25:22: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
23 | @staticmethod
|
||||
24 | def bad2(__self) -> None: ... # PYI063
|
||||
|
@ -55,7 +54,7 @@ PYI063.pyi:25:22: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:26:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:26:25: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
24 | def bad2(__self) -> None: ... # PYI063
|
||||
25 | def bad3(__self, __x: int) -> None: ... # PYI063
|
||||
|
@ -66,7 +65,7 @@ PYI063.pyi:26:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:28:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:28:25: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
26 | def still_bad(self, __x_: int) -> None: ... # PYI063 # TODO: doesn't get raised here
|
||||
27 | @staticmethod
|
||||
|
@ -77,7 +76,7 @@ PYI063.pyi:28:25: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:30:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:30:23: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
28 | def this_is_bad_too(__x: int) -> None: ... # PYI063
|
||||
29 | @classmethod
|
||||
|
@ -88,7 +87,7 @@ PYI063.pyi:30:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:52:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:52:23: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
50 | class Metaclass(type):
|
||||
51 | @classmethod
|
||||
|
@ -99,7 +98,7 @@ PYI063.pyi:52:23: PYI063 Use PEP 570 syntax for positional-only arguments
|
|||
|
|
||||
= help: Add `/` to function signature
|
||||
|
||||
PYI063.pyi:56:26: PYI063 Use PEP 570 syntax for positional-only arguments
|
||||
PYI063.pyi:56:26: PYI063 Use PEP 570 syntax for positional-only parameters
|
||||
|
|
||||
54 | class Metaclass2(type):
|
||||
55 | @classmethod
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
PYI066.pyi:3:4: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` comparisons
|
||||
PYI066.pyi:3:4: PYI066 Put branches for newer Python versions first when branching on `sys.version_info` comparisons
|
||||
|
|
||||
1 | import sys
|
||||
2 |
|
||||
|
@ -12,7 +11,7 @@ PYI066.pyi:3:4: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` c
|
|||
5 | else:
|
||||
|
|
||||
|
||||
PYI066.pyi:8:4: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` comparisons
|
||||
PYI066.pyi:8:4: PYI066 Put branches for newer Python versions first when branching on `sys.version_info` comparisons
|
||||
|
|
||||
6 | def foo(x, *, bar=True): ...
|
||||
7 |
|
||||
|
@ -22,7 +21,7 @@ PYI066.pyi:8:4: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` c
|
|||
10 | elif sys.version_info < (3, 9): # Y066 When using if/else with sys.version_info, put the code for new Python versions first, e.g. "if sys.version_info >= (3, 9)"
|
||||
|
|
||||
|
||||
PYI066.pyi:10:6: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` comparisons
|
||||
PYI066.pyi:10:6: PYI066 Put branches for newer Python versions first when branching on `sys.version_info` comparisons
|
||||
|
|
||||
8 | if sys.version_info < (3, 8): # Y066 When using if/else with sys.version_info, put the code for new Python versions first, e.g. "if sys.version_info >= (3, 8)"
|
||||
9 | def bar(x): ...
|
||||
|
@ -32,7 +31,7 @@ PYI066.pyi:10:6: PYI066 Use `>=` when using `if`-`else` with `sys.version_info`
|
|||
12 | elif sys.version_info < (3, 11): # Y066 When using if/else with sys.version_info, put the code for new Python versions first, e.g. "if sys.version_info >= (3, 10)"
|
||||
|
|
||||
|
||||
PYI066.pyi:12:6: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` comparisons
|
||||
PYI066.pyi:12:6: PYI066 Put branches for newer Python versions first when branching on `sys.version_info` comparisons
|
||||
|
|
||||
10 | elif sys.version_info < (3, 9): # Y066 When using if/else with sys.version_info, put the code for new Python versions first, e.g. "if sys.version_info >= (3, 9)"
|
||||
11 | def bar(x, *, bar=True): ...
|
||||
|
@ -42,7 +41,7 @@ PYI066.pyi:12:6: PYI066 Use `>=` when using `if`-`else` with `sys.version_info`
|
|||
14 | else:
|
||||
|
|
||||
|
||||
PYI066.pyi:20:6: PYI066 Use `>=` when using `if`-`else` with `sys.version_info` comparisons
|
||||
PYI066.pyi:20:6: PYI066 Put branches for newer Python versions first when branching on `sys.version_info` comparisons
|
||||
|
|
||||
18 | if sys.version_info >= (3, 5):
|
||||
19 | ...
|
||||
|
|
|
@ -6,14 +6,18 @@ use ruff_text_size::{Ranged, TextRange};
|
|||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for unnecessary default type arguments.
|
||||
/// Checks for unnecessary default type arguments for `Generator` and
|
||||
/// `AsyncGenerator` on Python 3.13+.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Python 3.13 introduced the ability for type parameters to specify default
|
||||
/// values. As such, the default type arguments for some types in the standard
|
||||
/// library (e.g., Generator, AsyncGenerator) are now optional.
|
||||
/// values. Following this change, several standard-library classes were
|
||||
/// updated to add default values for some of their type parameters. For
|
||||
/// example, `Generator[int]` is now equivalent to
|
||||
/// `Generator[int, None, None]`, as the second and third type parameters of
|
||||
/// `Generator` now default to `None`.
|
||||
///
|
||||
/// Omitting type parameters 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.
|
||||
///
|
||||
/// ## Examples
|
||||
|
|
|
@ -10,13 +10,15 @@ use crate::checkers::ast::Checker;
|
|||
/// Checks for uses of `assert expression, print(message)`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// The return value of the second expression is used as the contents of the
|
||||
/// `AssertionError` raised by the `assert` statement. Using a `print` expression
|
||||
/// in this context will output the message to `stdout`, before raising an
|
||||
/// empty `AssertionError(None)`.
|
||||
/// If an `assert x, y` assertion fails, the Python interpreter raises an
|
||||
/// `AssertionError`, and the evaluated value of `y` is used as the contents of
|
||||
/// that assertion error. The `print` function always returns `None`, however,
|
||||
/// so the evaluated value of a call to `print` will always be `None`.
|
||||
///
|
||||
/// Instead, remove the `print` and pass the message directly as the second
|
||||
/// expression, allowing `stderr` to capture the message in a well-formatted context.
|
||||
/// Using a `print` call in this context will therefore output the message to
|
||||
/// `stdout`, before raising an empty `AssertionError(None)`. Instead, remove
|
||||
/// the `print` and pass the message directly as the second expression,
|
||||
/// allowing `stderr` to capture the message in a well-formatted context.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
|
@ -41,7 +43,7 @@ pub struct AssertWithPrintMessage;
|
|||
impl AlwaysFixableViolation for AssertWithPrintMessage {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"`print()` expression in `assert` statement is likely unintentional".to_string()
|
||||
"`print()` call in `assert` statement is likely unintentional".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) use mutable_dataclass_default::*;
|
|||
pub(crate) use mutable_fromkeys_value::*;
|
||||
pub(crate) use never_union::*;
|
||||
pub(crate) use none_not_at_end_of_union::*;
|
||||
pub(crate) use parenthesize_logical_operators::*;
|
||||
pub(crate) use parenthesize_chained_operators::*;
|
||||
pub(crate) use post_init_default::*;
|
||||
pub(crate) use quadratic_list_summation::*;
|
||||
pub(crate) use redirected_noqa::*;
|
||||
|
@ -61,7 +61,7 @@ mod mutable_dataclass_default;
|
|||
mod mutable_fromkeys_value;
|
||||
mod never_union;
|
||||
mod none_not_at_end_of_union;
|
||||
mod parenthesize_logical_operators;
|
||||
mod parenthesize_chained_operators;
|
||||
mod post_init_default;
|
||||
mod quadratic_list_summation;
|
||||
mod redirected_noqa;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
RUF030.py:6:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:6:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
4 | # Expects:
|
||||
5 | # - single StringLiteral
|
||||
|
@ -23,7 +22,7 @@ RUF030.py:6:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
8 8 | # Concatenated string literals
|
||||
9 9 | # Expects:
|
||||
|
||||
RUF030.py:11:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:11:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
9 | # Expects:
|
||||
10 | # - single StringLiteral
|
||||
|
@ -44,7 +43,7 @@ RUF030.py:11:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
13 13 | # Positional arguments, string literals
|
||||
14 14 | # Expects:
|
||||
|
||||
RUF030.py:16:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:16:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
14 | # Expects:
|
||||
15 | # - single StringLiteral concatenated with " "
|
||||
|
@ -65,7 +64,7 @@ RUF030.py:16:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
18 18 | # Concatenated string literals combined with Positional arguments
|
||||
19 19 | # Expects:
|
||||
|
||||
RUF030.py:21:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:21:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
19 | # Expects:
|
||||
20 | # - single stringliteral concatenated with " " only between `print` and `is`
|
||||
|
@ -86,7 +85,7 @@ RUF030.py:21:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
23 23 | # Positional arguments, string literals with a variable
|
||||
24 24 | # Expects:
|
||||
|
||||
RUF030.py:26:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:26:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
24 | # Expects:
|
||||
25 | # - single FString concatenated with " "
|
||||
|
@ -107,7 +106,7 @@ RUF030.py:26:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
28 28 | # Mixed brackets string literals
|
||||
29 29 | # Expects:
|
||||
|
||||
RUF030.py:31:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:31:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
29 | # Expects:
|
||||
30 | # - single StringLiteral concatenated with " "
|
||||
|
@ -128,7 +127,7 @@ RUF030.py:31:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
33 33 | # Mixed brackets with other brackets inside
|
||||
34 34 | # Expects:
|
||||
|
||||
RUF030.py:36:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:36:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
34 | # Expects:
|
||||
35 | # - single StringLiteral concatenated with " " and escaped brackets
|
||||
|
@ -149,7 +148,7 @@ RUF030.py:36:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
38 38 | # Positional arguments, string literals with a separator
|
||||
39 39 | # Expects:
|
||||
|
||||
RUF030.py:41:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:41:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
39 | # Expects:
|
||||
40 | # - single StringLiteral concatenated with "|"
|
||||
|
@ -170,7 +169,7 @@ RUF030.py:41:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
43 43 | # Positional arguments, string literals with None as separator
|
||||
44 44 | # Expects:
|
||||
|
||||
RUF030.py:46:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:46:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
44 | # Expects:
|
||||
45 | # - single StringLiteral concatenated with " "
|
||||
|
@ -191,7 +190,7 @@ RUF030.py:46:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
48 48 | # Positional arguments, string literals with variable as separator, needs f-string
|
||||
49 49 | # Expects:
|
||||
|
||||
RUF030.py:51:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:51:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
49 | # Expects:
|
||||
50 | # - single FString concatenated with "{U00A0}"
|
||||
|
@ -212,7 +211,7 @@ RUF030.py:51:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
53 53 | # Unnecessary f-string
|
||||
54 54 | # Expects:
|
||||
|
||||
RUF030.py:56:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:56:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
54 | # Expects:
|
||||
55 | # - single StringLiteral
|
||||
|
@ -233,7 +232,7 @@ RUF030.py:56:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
58 58 | # Positional arguments, string literals and f-strings
|
||||
59 59 | # Expects:
|
||||
|
||||
RUF030.py:61:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:61:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
59 | # Expects:
|
||||
60 | # - single FString concatenated with " "
|
||||
|
@ -254,7 +253,7 @@ RUF030.py:61:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
63 63 | # Positional arguments, string literals and f-strings with a separator
|
||||
64 64 | # Expects:
|
||||
|
||||
RUF030.py:66:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:66:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
64 | # Expects:
|
||||
65 | # - single FString concatenated with "|"
|
||||
|
@ -275,7 +274,7 @@ RUF030.py:66:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
68 68 | # A single f-string
|
||||
69 69 | # Expects:
|
||||
|
||||
RUF030.py:71:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:71:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
69 | # Expects:
|
||||
70 | # - single FString
|
||||
|
@ -296,7 +295,7 @@ RUF030.py:71:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
73 73 | # A single f-string with a redundant separator
|
||||
74 74 | # Expects:
|
||||
|
||||
RUF030.py:76:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:76:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
74 | # Expects:
|
||||
75 | # - single FString
|
||||
|
@ -317,7 +316,7 @@ RUF030.py:76:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
78 78 | # Complex f-string with variable as separator
|
||||
79 79 | # Expects:
|
||||
|
||||
RUF030.py:83:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:83:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
81 | condition = "True is True"
|
||||
82 | maintainer = "John Doe"
|
||||
|
@ -338,7 +337,7 @@ RUF030.py:83:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
85 85 | # Empty print
|
||||
86 86 | # Expects:
|
||||
|
||||
RUF030.py:88:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:88:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
86 | # Expects:
|
||||
87 | # - `msg` entirely removed from assertion
|
||||
|
@ -359,7 +358,7 @@ RUF030.py:88:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
90 90 | # Empty print with separator
|
||||
91 91 | # Expects:
|
||||
|
||||
RUF030.py:93:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:93:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
91 | # Expects:
|
||||
92 | # - `msg` entirely removed from assertion
|
||||
|
@ -380,7 +379,7 @@ RUF030.py:93:14: RUF030 [*] `print()` expression in `assert` statement is likely
|
|||
95 95 | # Custom print function that actually returns a string
|
||||
96 96 | # Expects:
|
||||
|
||||
RUF030.py:108:14: RUF030 [*] `print()` expression in `assert` statement is likely unintentional
|
||||
RUF030.py:108:14: RUF030 [*] `print()` call in `assert` statement is likely unintentional
|
||||
|
|
||||
106 | # Expects:
|
||||
107 | # - single StringLiteral
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue