diff --git a/crates/ruff_linter/src/rules/pylint/rules/missing_maxsplit_arg.rs b/crates/ruff_linter/src/rules/pylint/rules/missing_maxsplit_arg.rs index 8fb8a52754f40a..85365af7ae0d04 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/missing_maxsplit_arg.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/missing_maxsplit_arg.rs @@ -11,13 +11,13 @@ use crate::fix; use crate::{AlwaysFixableViolation, Applicability, Edit, Fix}; /// ## What it does -/// Checks for access to the first or last element of `str.split()` or `str.rsplit()` without -/// `maxsplit=1` +/// Checks for access to the first or last element of `str.split()` or `str.rsplit()` without a +/// `maxsplit=1` argument. /// /// ## Why is this bad? /// Calling `str.split()` or `str.rsplit()` without passing `maxsplit=1` splits on every delimiter in the /// string. When accessing only the first or last element of the result, it -/// would be more efficient to only split once. +/// would be more efficient to split only once. /// /// ## Example /// ```python @@ -38,13 +38,14 @@ use crate::{AlwaysFixableViolation, Applicability, Edit, Fix}; /// ``` /// /// ## Fix Safety -/// This rule's fix is marked as unsafe for `split()`/`rsplit()` calls that contain `*args` or `**kwargs` arguments, as -/// adding a `maxsplit` argument to such a call may lead to duplicated arguments. +/// This rule's fix is marked as unsafe for `split()`/`rsplit()` calls that contain `*args` or +/// `**kwargs` arguments, as adding a `maxsplit` argument to such a call may lead to duplicate +/// arguments. #[derive(ViolationMetadata)] -#[violation_metadata(preview_since = "0.11.12")] -pub(crate) struct MissingMaxsplitArg { - actual_split_type: String, - suggested_split_type: String, +#[violation_metadata(stable_since = "0.15.0")] +pub(crate) struct MissingMaxsplitArg<'a> { + actual_split_type: &'a str, + suggested_split_type: &'a str, } /// Represents the index of the slice used for this rule (which can only be 0 or -1) @@ -53,15 +54,10 @@ enum SliceBoundary { Last, } -impl AlwaysFixableViolation for MissingMaxsplitArg { +impl AlwaysFixableViolation for MissingMaxsplitArg<'_> { #[derive_message_formats] fn message(&self) -> String { - let MissingMaxsplitArg { - actual_split_type: _, - suggested_split_type, - } = self; - - format!("Replace with `{suggested_split_type}(..., maxsplit=1)`.") + "String is split more times than necessary".to_string() } fn fix_title(&self) -> String { @@ -189,8 +185,8 @@ pub(crate) fn missing_maxsplit_arg(checker: &Checker, value: &Expr, slice: &Expr let mut diagnostic = checker.report_diagnostic( MissingMaxsplitArg { - actual_split_type: actual_split_type.to_string(), - suggested_split_type: suggested_split_type.to_string(), + actual_split_type, + suggested_split_type, }, expr.range(), ); diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0207_missing_maxsplit_arg.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0207_missing_maxsplit_arg.py.snap index 7b5f384b4974b8..faf31f932ae0f8 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0207_missing_maxsplit_arg.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0207_missing_maxsplit_arg.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:14:1 | 12 | # Errors @@ -21,7 +21,7 @@ help: Pass `maxsplit=1` into `str.split()` 16 | "1,2,3".rsplit(",")[0] # [missing-maxsplit-arg] 17 | "1,2,3".rsplit(",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:15:1 | 13 | ## Test split called directly on string literal @@ -41,7 +41,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 17 | "1,2,3".rsplit(",")[-1] # [missing-maxsplit-arg] 18 | -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:16:1 | 14 | "1,2,3".split(",")[0] # [missing-maxsplit-arg] @@ -60,7 +60,7 @@ help: Use `str.split()` and pass `maxsplit=1` 18 | 19 | ## Test split called on string variable -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:17:1 | 15 | "1,2,3".split(",")[-1] # [missing-maxsplit-arg] @@ -80,7 +80,7 @@ help: Pass `maxsplit=1` into `str.rsplit()` 19 | ## Test split called on string variable 20 | SEQ.split(",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:20:1 | 19 | ## Test split called on string variable @@ -99,7 +99,7 @@ help: Pass `maxsplit=1` into `str.split()` 22 | SEQ.rsplit(",")[0] # [missing-maxsplit-arg] 23 | SEQ.rsplit(",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:21:1 | 19 | ## Test split called on string variable @@ -119,7 +119,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 23 | SEQ.rsplit(",")[-1] # [missing-maxsplit-arg] 24 | -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:22:1 | 20 | SEQ.split(",")[0] # [missing-maxsplit-arg] @@ -138,7 +138,7 @@ help: Use `str.split()` and pass `maxsplit=1` 24 | 25 | ## Test split called on class attribute -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:23:1 | 21 | SEQ.split(",")[-1] # [missing-maxsplit-arg] @@ -158,7 +158,7 @@ help: Pass `maxsplit=1` into `str.rsplit()` 25 | ## Test split called on class attribute 26 | Foo.class_str.split(",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:26:1 | 25 | ## Test split called on class attribute @@ -177,7 +177,7 @@ help: Pass `maxsplit=1` into `str.split()` 28 | Foo.class_str.rsplit(",")[0] # [missing-maxsplit-arg] 29 | Foo.class_str.rsplit(",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:27:1 | 25 | ## Test split called on class attribute @@ -197,7 +197,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 29 | Foo.class_str.rsplit(",")[-1] # [missing-maxsplit-arg] 30 | -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:28:1 | 26 | Foo.class_str.split(",")[0] # [missing-maxsplit-arg] @@ -216,7 +216,7 @@ help: Use `str.split()` and pass `maxsplit=1` 30 | 31 | ## Test split called on sliced string -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:29:1 | 27 | Foo.class_str.split(",")[-1] # [missing-maxsplit-arg] @@ -236,7 +236,7 @@ help: Pass `maxsplit=1` into `str.rsplit()` 31 | ## Test split called on sliced string 32 | "1,2,3"[::-1].split(",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:32:1 | 31 | ## Test split called on sliced string @@ -255,7 +255,7 @@ help: Pass `maxsplit=1` into `str.split()` 34 | SEQ[:3].split(",")[0] # [missing-maxsplit-arg] 35 | Foo.class_str[1:3].split(",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:33:1 | 31 | ## Test split called on sliced string @@ -275,7 +275,7 @@ help: Pass `maxsplit=1` into `str.split()` 35 | Foo.class_str[1:3].split(",")[-1] # [missing-maxsplit-arg] 36 | "1,2,3"[::-1].rsplit(",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:34:1 | 32 | "1,2,3"[::-1].split(",")[0] # [missing-maxsplit-arg] @@ -295,7 +295,7 @@ help: Pass `maxsplit=1` into `str.split()` 36 | "1,2,3"[::-1].rsplit(",")[0] # [missing-maxsplit-arg] 37 | SEQ[:3].rsplit(",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:35:1 | 33 | "1,2,3"[::-1][::-1].split(",")[0] # [missing-maxsplit-arg] @@ -315,7 +315,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 37 | SEQ[:3].rsplit(",")[0] # [missing-maxsplit-arg] 38 | Foo.class_str[1:3].rsplit(",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:36:1 | 34 | SEQ[:3].split(",")[0] # [missing-maxsplit-arg] @@ -335,7 +335,7 @@ help: Use `str.split()` and pass `maxsplit=1` 38 | Foo.class_str[1:3].rsplit(",")[-1] # [missing-maxsplit-arg] 39 | -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:37:1 | 35 | Foo.class_str[1:3].split(",")[-1] # [missing-maxsplit-arg] @@ -354,7 +354,7 @@ help: Use `str.split()` and pass `maxsplit=1` 39 | 40 | ## Test sep given as named argument -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:38:1 | 36 | "1,2,3"[::-1].rsplit(",")[0] # [missing-maxsplit-arg] @@ -374,7 +374,7 @@ help: Pass `maxsplit=1` into `str.rsplit()` 40 | ## Test sep given as named argument 41 | "1,2,3".split(sep=",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:41:1 | 40 | ## Test sep given as named argument @@ -393,7 +393,7 @@ help: Pass `maxsplit=1` into `str.split()` 43 | "1,2,3".rsplit(sep=",")[0] # [missing-maxsplit-arg] 44 | "1,2,3".rsplit(sep=",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:42:1 | 40 | ## Test sep given as named argument @@ -413,7 +413,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 44 | "1,2,3".rsplit(sep=",")[-1] # [missing-maxsplit-arg] 45 | -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:43:1 | 41 | "1,2,3".split(sep=",")[0] # [missing-maxsplit-arg] @@ -432,7 +432,7 @@ help: Use `str.split()` and pass `maxsplit=1` 45 | 46 | ## Special cases -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:44:1 | 42 | "1,2,3".split(sep=",")[-1] # [missing-maxsplit-arg] @@ -452,7 +452,7 @@ help: Pass `maxsplit=1` into `str.rsplit()` 46 | ## Special cases 47 | "1,2,3".split("\n")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:47:1 | 46 | ## Special cases @@ -471,7 +471,7 @@ help: Pass `maxsplit=1` into `str.split()` 49 | "1,2,3".rsplit("rsplit")[0] # [missing-maxsplit-arg] 50 | -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:48:1 | 46 | ## Special cases @@ -490,7 +490,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 50 | 51 | ## Test class attribute named split -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:49:1 | 47 | "1,2,3".split("\n")[0] # [missing-maxsplit-arg] @@ -510,7 +510,7 @@ help: Use `str.split()` and pass `maxsplit=1` 51 | ## Test class attribute named split 52 | Bar.split.split(",")[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:52:1 | 51 | ## Test class attribute named split @@ -529,7 +529,7 @@ help: Pass `maxsplit=1` into `str.split()` 54 | Bar.split.rsplit(",")[0] # [missing-maxsplit-arg] 55 | Bar.split.rsplit(",")[-1] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:53:1 | 51 | ## Test class attribute named split @@ -549,7 +549,7 @@ help: Use `str.rsplit()` and pass `maxsplit=1` 55 | Bar.split.rsplit(",")[-1] # [missing-maxsplit-arg] 56 | -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:54:1 | 52 | Bar.split.split(",")[0] # [missing-maxsplit-arg] @@ -568,7 +568,7 @@ help: Use `str.split()` and pass `maxsplit=1` 56 | 57 | ## Test unpacked dict literal kwargs -PLC0207 [*] Replace with `rsplit(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:55:1 | 53 | Bar.split.split(",")[-1] # [missing-maxsplit-arg] @@ -588,7 +588,7 @@ help: Pass `maxsplit=1` into `str.rsplit()` 57 | ## Test unpacked dict literal kwargs 58 | "1,2,3".split(**{"sep": ","})[0] # [missing-maxsplit-arg] -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:58:1 | 57 | ## Test unpacked dict literal kwargs @@ -606,7 +606,7 @@ help: Pass `maxsplit=1` into `str.split()` 61 | # OK note: This is an unsafe fix and may change runtime behavior -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:179:1 | 177 | # Errors @@ -627,7 +627,7 @@ help: Pass `maxsplit=1` into `str.split()` 182 | "1,2,3".split(",", **kwargs_with_maxsplit)[0] # TODO: false positive note: This is an unsafe fix and may change runtime behavior -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:182:1 | 180 | # OK @@ -648,7 +648,7 @@ help: Pass `maxsplit=1` into `str.split()` 185 | note: This is an unsafe fix and may change runtime behavior -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:184:1 | 182 | "1,2,3".split(",", **kwargs_with_maxsplit)[0] # TODO: false positive @@ -667,7 +667,7 @@ help: Pass `maxsplit=1` into `str.split()` 187 | ## Test unpacked list literal args (starred expressions) note: This is an unsafe fix and may change runtime behavior -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:189:1 | 187 | ## Test unpacked list literal args (starred expressions) @@ -688,7 +688,7 @@ help: Pass `maxsplit=1` into `str.split()` 192 | # Errors note: This is an unsafe fix and may change runtime behavior -PLC0207 [*] Replace with `split(..., maxsplit=1)`. +PLC0207 [*] String is split more times than necessary --> missing_maxsplit_arg.py:194:1 | 192 | # Errors