Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions crates/ruff_linter/src/rules/pylint/rules/missing_maxsplit_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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 {
Expand Down Expand Up @@ -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(),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down