From 4559f26f7690ae477055064eaddff0a24cf6002a Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 13:13:36 -0500 Subject: [PATCH 01/28] preserve triple quoting --- .../src/types/display.rs | 2 +- crates/ruff_python_codegen/src/generator.rs | 51 +++++++++++++--- crates/ruff_python_literal/src/escape.rs | 58 ++++++++++++++----- 3 files changed, 87 insertions(+), 24 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types/display.rs b/crates/red_knot_python_semantic/src/types/display.rs index 50c3ae1fff8cb..ac02e57b24c19 100644 --- a/crates/red_knot_python_semantic/src/types/display.rs +++ b/crates/red_knot_python_semantic/src/types/display.rs @@ -98,7 +98,7 @@ impl Display for DisplayRepresentation<'_> { let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db).as_ref(), Quote::Double); - escape.bytes_repr().write(f) + escape.bytes_repr(false).write(f) } Type::SliceLiteral(slice) => { f.write_str("slice[")?; diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 587e805219908..d63dce5db46d3 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -146,20 +146,26 @@ impl<'a> Generator<'a> { self.p(s.as_str()); } - fn p_bytes_repr(&mut self, s: &[u8], quote: Quote) { + fn p_bytes_repr(&mut self, s: &[u8], quote: Quote, triple_quote: bool) { let escape = AsciiEscape::with_preferred_quote(s, quote); if let Some(len) = escape.layout().len { self.buffer.reserve(len); } - escape.bytes_repr().write(&mut self.buffer).unwrap(); // write to string doesn't fail + escape + .bytes_repr(triple_quote) + .write(&mut self.buffer) + .unwrap(); // write to string doesn't fail } - fn p_str_repr(&mut self, s: &str, quote: Quote) { + fn p_str_repr(&mut self, s: &str, quote: Quote, triple_quote: bool) { let escape = UnicodeEscape::with_preferred_quote(s, quote); if let Some(len) = escape.layout().len { self.buffer.reserve(len); } - escape.str_repr().write(&mut self.buffer).unwrap(); // write to string doesn't fail + escape + .str_repr(triple_quote) + .write(&mut self.buffer) + .unwrap(); // write to string doesn't fail } fn p_if(&mut self, cond: bool, s: &str) { @@ -1093,7 +1099,11 @@ impl<'a> Generator<'a> { let mut first = true; for bytes_literal in value { self.p_delim(&mut first, " "); - self.p_bytes_repr(&bytes_literal.value, bytes_literal.flags.quote_style()); + self.p_bytes_repr( + &bytes_literal.value, + bytes_literal.flags.quote_style(), + bytes_literal.flags.is_triple_quoted(), + ); } } Expr::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => { @@ -1291,7 +1301,7 @@ impl<'a> Generator<'a> { if flags.prefix().is_unicode() { self.p("u"); } - self.p_str_repr(value, flags.quote_style()); + self.p_str_repr(value, flags.quote_style(), flags.is_triple_quoted()); } } @@ -1312,7 +1322,11 @@ impl<'a> Generator<'a> { self.unparse_string_literal(string_literal); } ast::FStringPart::FString(f_string) => { - self.unparse_f_string(&f_string.elements, f_string.flags.quote_style()); + self.unparse_f_string( + &f_string.elements, + f_string.flags.quote_style(), + f_string.flags.is_triple_quoted(), + ); } } } @@ -1396,12 +1410,17 @@ impl<'a> Generator<'a> { /// Unparse `values` with [`Generator::unparse_f_string_body`], using `quote` as the preferred /// surrounding quote style. - fn unparse_f_string(&mut self, values: &[ast::FStringElement], quote: Quote) { + fn unparse_f_string( + &mut self, + values: &[ast::FStringElement], + quote: Quote, + triple_quote: bool, + ) { self.p("f"); let mut generator = Generator::new(self.indent, self.line_ending); generator.unparse_f_string_body(values); let body = &generator.buffer; - self.p_str_repr(body, quote); + self.p_str_repr(body, quote, triple_quote); } fn unparse_alias(&mut self, alias: &Alias) { @@ -1726,6 +1745,20 @@ class Foo: assert_eq!(round_trip(r#""he\"llo""#), r#"'he"llo'"#); assert_eq!(round_trip(r#"f"abc{'def'}{1}""#), r#"f"abc{'def'}{1}""#); assert_round_trip!(r#"f'abc{"def"}{1}'"#); + // triple double quotes should be preserved for all string types + assert_round_trip!(r#""""hello""""#); + assert_round_trip!(r#"u"""hello""""#); + assert_round_trip!(r#"r"""hello""""#); + assert_round_trip!(r#"b"""hello""""#); + assert_round_trip!(r#"f"""hello""""#); + assert_round_trip!(r#"f"""{hello}""""#); + // same for triple single quotes + assert_round_trip!(r#"'''hello'''"#); + assert_round_trip!(r#"u'''hello'''"#); + assert_round_trip!(r#"r'''hello'''"#); + assert_round_trip!(r#"b'''hello'''"#); + assert_round_trip!(r#"f'''hello'''"#); + assert_round_trip!(r#"f'''{hello}'''"#); } #[test] diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 91157b57109ec..8a574d1b49171 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -60,23 +60,38 @@ impl<'a> UnicodeEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn str_repr<'r>(&'a self) -> StrRepr<'r, 'a> { - StrRepr(self) + pub fn str_repr<'r>(&'a self, triple_quote: bool) -> StrRepr<'r, 'a> { + StrRepr { + escape: self, + triple_quote, + } } } -pub struct StrRepr<'r, 'a>(&'r UnicodeEscape<'a>); +pub struct StrRepr<'r, 'a> { + escape: &'r UnicodeEscape<'a>, + triple_quote: bool, +} impl StrRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { - let quote = self.0.layout().quote.as_char(); + let quote = self.escape.layout().quote.as_char(); + formatter.write_char(quote)?; + if self.triple_quote { + formatter.write_char(quote)?; + formatter.write_char(quote)?; + } + self.escape.write_body(formatter)?; formatter.write_char(quote)?; - self.0.write_body(formatter)?; - formatter.write_char(quote) + if self.triple_quote { + formatter.write_char(quote)?; + formatter.write_char(quote)?; + } + Ok(()) } pub fn to_string(&self) -> Option { - let mut s = String::with_capacity(self.0.layout().len?); + let mut s = String::with_capacity(self.escape.layout().len?); self.write(&mut s).unwrap(); Some(s) } @@ -244,8 +259,11 @@ impl<'a> AsciiEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn bytes_repr<'r>(&'a self) -> BytesRepr<'r, 'a> { - BytesRepr(self) + pub fn bytes_repr<'r>(&'a self, triple_quote: bool) -> BytesRepr<'r, 'a> { + BytesRepr { + escape: self, + triple_quote, + } } } @@ -360,19 +378,31 @@ impl Escape for AsciiEscape<'_> { } } -pub struct BytesRepr<'r, 'a>(&'r AsciiEscape<'a>); +pub struct BytesRepr<'r, 'a> { + escape: &'r AsciiEscape<'a>, + triple_quote: bool, +} impl BytesRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { - let quote = self.0.layout().quote.as_char(); + let quote = self.escape.layout().quote.as_char(); formatter.write_char('b')?; formatter.write_char(quote)?; - self.0.write_body(formatter)?; - formatter.write_char(quote) + if self.triple_quote { + formatter.write_char(quote)?; + formatter.write_char(quote)?; + } + self.escape.write_body(formatter)?; + formatter.write_char(quote)?; + if self.triple_quote { + formatter.write_char(quote)?; + formatter.write_char(quote)?; + } + Ok(()) } pub fn to_string(&self) -> Option { - let mut s = String::with_capacity(self.0.layout().len?); + let mut s = String::with_capacity(self.escape.layout().len?); self.write(&mut s).unwrap(); Some(s) } From de72a61dc4095cc4cecb0f8d5f0b2a616f571267 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 13:09:45 -0500 Subject: [PATCH 02/28] unset triple quotes for SIM905 fix, add without_triple_quotes method --- .../flake8_simplify/rules/split_static_string.rs | 12 +++++++++++- crates/ruff_python_ast/src/nodes.rs | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs index f22e7d8664e6b..8f0d6d6082d62 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs @@ -123,7 +123,17 @@ fn construct_replacement(elts: &[&str], flags: StringLiteralFlags) -> Expr { Expr::from(StringLiteral { value: Box::from(*elt), range: TextRange::default(), - flags, + // intentionally omit the triple quote flag, if set, to avoid strange + // replacements like + // + // ```python + // """ + // itemA + // itemB + // itemC + // """.split() # -> ["""itemA""", """itemB""", """itemC"""] + // ``` + flags: flags.without_triple_quotes(), }) }) .collect(), diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 3727e43cd70d2..705a391a7d3b8 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1482,6 +1482,12 @@ impl StringLiteralFlags { self } + #[must_use] + pub fn without_triple_quotes(mut self) -> Self { + self.0.remove(StringLiteralFlagsInner::TRIPLE_QUOTED); + self + } + #[must_use] pub fn with_prefix(self, prefix: StringLiteralPrefix) -> Self { let StringLiteralFlags(flags) = self; From 59067bdd25618a175d19e17a7c2104060888332c Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 13:25:59 -0500 Subject: [PATCH 03/28] pass flags instead of separate quote and triple_quote values --- crates/ruff_python_codegen/src/generator.rs | 45 ++++++++------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index d63dce5db46d3..b0a3f7fe5ac76 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -2,12 +2,11 @@ use std::ops::Deref; -use ruff_python_ast::str::Quote; use ruff_python_ast::{ - self as ast, Alias, ArgOrKeyword, BoolOp, CmpOp, Comprehension, ConversionFlag, DebugText, - ExceptHandler, Expr, Identifier, MatchCase, Operator, Parameter, Parameters, Pattern, - Singleton, Stmt, StringFlags, Suite, TypeParam, TypeParamParamSpec, TypeParamTypeVar, - TypeParamTypeVarTuple, WithItem, + self as ast, Alias, AnyStringFlags, ArgOrKeyword, BoolOp, BytesLiteralFlags, CmpOp, + Comprehension, ConversionFlag, DebugText, ExceptHandler, Expr, FStringFlags, Identifier, + MatchCase, Operator, Parameter, Parameters, Pattern, Singleton, Stmt, StringFlags, Suite, + TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, WithItem, }; use ruff_python_ast::{ParameterWithDefault, TypeParams}; use ruff_python_literal::escape::{AsciiEscape, Escape, UnicodeEscape}; @@ -146,24 +145,25 @@ impl<'a> Generator<'a> { self.p(s.as_str()); } - fn p_bytes_repr(&mut self, s: &[u8], quote: Quote, triple_quote: bool) { - let escape = AsciiEscape::with_preferred_quote(s, quote); + fn p_bytes_repr(&mut self, s: &[u8], flags: BytesLiteralFlags) { + let escape = AsciiEscape::with_preferred_quote(s, flags.quote_style()); if let Some(len) = escape.layout().len { self.buffer.reserve(len); } escape - .bytes_repr(triple_quote) + .bytes_repr(flags.is_triple_quoted()) .write(&mut self.buffer) .unwrap(); // write to string doesn't fail } - fn p_str_repr(&mut self, s: &str, quote: Quote, triple_quote: bool) { - let escape = UnicodeEscape::with_preferred_quote(s, quote); + fn p_str_repr(&mut self, s: &str, flags: impl Into) { + let flags = flags.into(); + let escape = UnicodeEscape::with_preferred_quote(s, flags.quote_style()); if let Some(len) = escape.layout().len { self.buffer.reserve(len); } escape - .str_repr(triple_quote) + .str_repr(flags.is_triple_quoted()) .write(&mut self.buffer) .unwrap(); // write to string doesn't fail } @@ -1099,11 +1099,7 @@ impl<'a> Generator<'a> { let mut first = true; for bytes_literal in value { self.p_delim(&mut first, " "); - self.p_bytes_repr( - &bytes_literal.value, - bytes_literal.flags.quote_style(), - bytes_literal.flags.is_triple_quoted(), - ); + self.p_bytes_repr(&bytes_literal.value, bytes_literal.flags); } } Expr::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => { @@ -1301,7 +1297,7 @@ impl<'a> Generator<'a> { if flags.prefix().is_unicode() { self.p("u"); } - self.p_str_repr(value, flags.quote_style(), flags.is_triple_quoted()); + self.p_str_repr(value, *flags); } } @@ -1322,11 +1318,7 @@ impl<'a> Generator<'a> { self.unparse_string_literal(string_literal); } ast::FStringPart::FString(f_string) => { - self.unparse_f_string( - &f_string.elements, - f_string.flags.quote_style(), - f_string.flags.is_triple_quoted(), - ); + self.unparse_f_string(&f_string.elements, f_string.flags); } } } @@ -1410,17 +1402,12 @@ impl<'a> Generator<'a> { /// Unparse `values` with [`Generator::unparse_f_string_body`], using `quote` as the preferred /// surrounding quote style. - fn unparse_f_string( - &mut self, - values: &[ast::FStringElement], - quote: Quote, - triple_quote: bool, - ) { + fn unparse_f_string(&mut self, values: &[ast::FStringElement], flags: FStringFlags) { self.p("f"); let mut generator = Generator::new(self.indent, self.line_ending); generator.unparse_f_string_body(values); let body = &generator.buffer; - self.p_str_repr(body, quote, triple_quote); + self.p_str_repr(body, flags); } fn unparse_alias(&mut self, alias: &Alias) { From 5354c0cbe00f855a9a13c591b719f967716b057c Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 16:12:02 -0500 Subject: [PATCH 04/28] move prefix logic into p_str_repr --- crates/ruff_python_codegen/src/generator.rs | 23 ++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index b0a3f7fe5ac76..19b7851424c00 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -158,6 +158,14 @@ impl<'a> Generator<'a> { fn p_str_repr(&mut self, s: &str, flags: impl Into) { let flags = flags.into(); + if flags.prefix().is_raw() { + self.p(flags.prefix().as_str()); + self.p(flags.quote_str()); + self.p(s); + self.p(flags.quote_str()); + return; + } + self.p(flags.prefix().as_str()); let escape = UnicodeEscape::with_preferred_quote(s, flags.quote_style()); if let Some(len) = escape.layout().len { self.buffer.reserve(len); @@ -1286,19 +1294,7 @@ impl<'a> Generator<'a> { fn unparse_string_literal(&mut self, string_literal: &ast::StringLiteral) { let ast::StringLiteral { value, flags, .. } = string_literal; - // for raw strings, we don't want to perform the UnicodeEscape in `p_str_repr`, so build the - // replacement here - if flags.prefix().is_raw() { - self.p(flags.prefix().as_str()); - self.p(flags.quote_str()); - self.p(value); - self.p(flags.quote_str()); - } else { - if flags.prefix().is_unicode() { - self.p("u"); - } - self.p_str_repr(value, *flags); - } + self.p_str_repr(value, *flags); } fn unparse_string_literal_value(&mut self, value: &ast::StringLiteralValue) { @@ -1403,7 +1399,6 @@ impl<'a> Generator<'a> { /// Unparse `values` with [`Generator::unparse_f_string_body`], using `quote` as the preferred /// surrounding quote style. fn unparse_f_string(&mut self, values: &[ast::FStringElement], flags: FStringFlags) { - self.p("f"); let mut generator = Generator::new(self.indent, self.line_ending); generator.unparse_f_string_body(values); let body = &generator.buffer; From 7d938680c72b81a322c8d20f95c8a12537e48323 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 16:12:27 -0500 Subject: [PATCH 05/28] handle prefixes for bytestrings --- crates/ruff_python_codegen/src/generator.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 19b7851424c00..efaa005745565 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -146,6 +146,11 @@ impl<'a> Generator<'a> { } fn p_bytes_repr(&mut self, s: &[u8], flags: BytesLiteralFlags) { + // raw bytes are interpreted without escapes and should all be ascii, but double check + // before writing to self + if flags.prefix().is_raw() && self.p_raw_bytes(s, flags).is_ok() { + return; + } let escape = AsciiEscape::with_preferred_quote(s, flags.quote_style()); if let Some(len) = escape.layout().len { self.buffer.reserve(len); @@ -156,6 +161,21 @@ impl<'a> Generator<'a> { .unwrap(); // write to string doesn't fail } + /// Returns a [`std::str::Utf8Error`] if `s` is not valid UTF-8, otherwise converts `s` to a + /// `str` and adds it to `self`. + fn p_raw_bytes( + &mut self, + s: &[u8], + flags: BytesLiteralFlags, + ) -> Result<(), std::str::Utf8Error> { + let body = std::str::from_utf8(s)?; + self.p(flags.prefix().as_str()); + self.p(flags.quote_str()); + self.p(body); + self.p(flags.quote_str()); + Ok(()) + } + fn p_str_repr(&mut self, s: &str, flags: impl Into) { let flags = flags.into(); if flags.prefix().is_raw() { From 4c85aadbd0fd84d4515f1fab93147e3883c79fae Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 16:12:38 -0500 Subject: [PATCH 06/28] test all prefix and quote combinations --- crates/ruff_python_codegen/src/generator.rs | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index efaa005745565..5746aaaaa773f 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1761,6 +1761,49 @@ class Foo: assert_round_trip!(r#"b'''hello'''"#); assert_round_trip!(r#"f'''hello'''"#); assert_round_trip!(r#"f'''{hello}'''"#); + + // all of the valid string literal prefix and quote combinations from + // https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals + let string_prefixes = [ + ("r", "r"), + ("u", "u"), + ("R", "R"), + ("U", "u"), // case not tracked + ("f", "f"), + ("F", "f"), // f case not tracked + ("fr", "rf"), // r before f + ("Fr", "rf"), // f case not tracked, r before f + ("fR", "Rf"), // r before f + ("FR", "Rf"), // f case not tracked, r before f + ("rf", "rf"), + ("rF", "rf"), // f case not tracked + ("Rf", "Rf"), + ("RF", "Rf"), // f case not tracked + // bytestrings + ("b", "b"), + ("B", "b"), // b case + ("br", "rb"), // r before b + ("Br", "rb"), // b case, r before b + ("bR", "Rb"), // r before b + ("BR", "Rb"), // b case, r before b + ("rb", "rb"), + ("rB", "rb"), // b case + ("Rb", "Rb"), + ("RB", "Rb"), // b case + ]; + let quotes = ["\"", "'", "\"\"\"", "'''"]; + for (inp, out) in string_prefixes { + for q in quotes { + let input = format!("{inp}{q}hello{q}"); + let output = format!("{out}{q}hello{q}"); + assert_eq!(round_trip(&input), output); + + // variants with f-string patterns + let input = format!("{inp}{q}{{hello}} {{world}}{q}"); + let output = format!("{out}{q}{{hello}} {{world}}{q}"); + assert_eq!(round_trip(&input), output); + } + } } #[test] From 13e6e7aef263e9411d126aa04e6428e7d415ea29 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 17:33:40 -0500 Subject: [PATCH 07/28] add *Flags::without_triple_quotes --- crates/ruff_python_ast/src/nodes.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 705a391a7d3b8..57773bb7af001 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1102,6 +1102,12 @@ impl FStringFlags { self } + #[must_use] + pub fn without_triple_quotes(mut self) -> Self { + self.0.remove(FStringFlagsInner::TRIPLE_QUOTED); + self + } + #[must_use] pub fn with_prefix(mut self, prefix: FStringPrefix) -> Self { match prefix { @@ -1877,6 +1883,12 @@ impl BytesLiteralFlags { self } + #[must_use] + pub fn without_triple_quotes(mut self) -> Self { + self.0.remove(BytesLiteralFlagsInner::TRIPLE_QUOTED); + self + } + #[must_use] pub fn with_prefix(mut self, prefix: ByteStringPrefix) -> Self { match prefix { @@ -2124,6 +2136,12 @@ impl AnyStringFlags { self.0 |= AnyStringFlagsInner::TRIPLE_QUOTED; self } + + #[must_use] + pub fn without_triple_quotes(mut self) -> Self { + self.0.remove(AnyStringFlagsInner::TRIPLE_QUOTED); + self + } } impl StringFlags for AnyStringFlags { From 6b0efc8a4996eeeb4588dd2846e11f94080a1cbd Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 17:42:32 -0500 Subject: [PATCH 08/28] use format_string_contents --- crates/ruff_python_codegen/src/generator.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 5746aaaaa773f..c8ca4fc2d3765 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -169,20 +169,14 @@ impl<'a> Generator<'a> { flags: BytesLiteralFlags, ) -> Result<(), std::str::Utf8Error> { let body = std::str::from_utf8(s)?; - self.p(flags.prefix().as_str()); - self.p(flags.quote_str()); - self.p(body); - self.p(flags.quote_str()); + self.p(&flags.format_string_contents(body)); Ok(()) } fn p_str_repr(&mut self, s: &str, flags: impl Into) { let flags = flags.into(); if flags.prefix().is_raw() { - self.p(flags.prefix().as_str()); - self.p(flags.quote_str()); - self.p(s); - self.p(flags.quote_str()); + self.p(&flags.format_string_contents(s)); return; } self.p(flags.prefix().as_str()); From 048389355db337c5e3a3f32a529f45a77175e3ba Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 17:44:12 -0500 Subject: [PATCH 09/28] unwrap -> expect Co-authored-by: Alex Waygood --- crates/ruff_python_codegen/src/generator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index c8ca4fc2d3765..47042d4d46755 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -158,7 +158,7 @@ impl<'a> Generator<'a> { escape .bytes_repr(flags.is_triple_quoted()) .write(&mut self.buffer) - .unwrap(); // write to string doesn't fail + .expect("Writing to a String buffer should never fail"); } /// Returns a [`std::str::Utf8Error`] if `s` is not valid UTF-8, otherwise converts `s` to a @@ -187,7 +187,7 @@ impl<'a> Generator<'a> { escape .str_repr(flags.is_triple_quoted()) .write(&mut self.buffer) - .unwrap(); // write to string doesn't fail + .expect("Writing to a String buffer should never fail"); } fn p_if(&mut self, cond: bool, s: &str) { From 7dcc98e71e5a0382a059e7e60dc6d5d4bd75a08e Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 18:33:59 -0500 Subject: [PATCH 10/28] use a matrix for prefix-quote tests --- Cargo.lock | 1 + crates/ruff_python_codegen/Cargo.toml | 2 + crates/ruff_python_codegen/src/generator.rs | 81 ++++++++++----------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f06613f0ba1fc..f1d13616c460c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2968,6 +2968,7 @@ dependencies = [ "ruff_python_parser", "ruff_source_file", "ruff_text_size", + "test-case", ] [[package]] diff --git a/crates/ruff_python_codegen/Cargo.toml b/crates/ruff_python_codegen/Cargo.toml index 35dcbc30116d9..57a400ec825cf 100644 --- a/crates/ruff_python_codegen/Cargo.toml +++ b/crates/ruff_python_codegen/Cargo.toml @@ -20,6 +20,8 @@ ruff_python_parser = { workspace = true } ruff_source_file = { workspace = true } ruff_text_size = { workspace = true } +[dev-dependencies] +test-case = { workspace = true } [lints] workspace = true diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 47042d4d46755..1f6d5a1f8f978 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1755,49 +1755,48 @@ class Foo: assert_round_trip!(r#"b'''hello'''"#); assert_round_trip!(r#"f'''hello'''"#); assert_round_trip!(r#"f'''{hello}'''"#); + } - // all of the valid string literal prefix and quote combinations from - // https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals - let string_prefixes = [ - ("r", "r"), - ("u", "u"), - ("R", "R"), - ("U", "u"), // case not tracked - ("f", "f"), - ("F", "f"), // f case not tracked - ("fr", "rf"), // r before f - ("Fr", "rf"), // f case not tracked, r before f - ("fR", "Rf"), // r before f - ("FR", "Rf"), // f case not tracked, r before f - ("rf", "rf"), - ("rF", "rf"), // f case not tracked - ("Rf", "Rf"), - ("RF", "Rf"), // f case not tracked + /// test all of the valid string literal prefix and quote combinations from + /// https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals + /// + /// Note that the numeric ids on the input/output and quote fields prevent name conflicts from + /// the test_matrix but are otherwise unnecessary + #[test_case::test_matrix( + [ + ("r", "r", 0), + ("u", "u", 1), + ("R", "R", 2), + ("U", "u", 3), // case not tracked + ("f", "f", 4), + ("F", "f", 5), // f case not tracked + ("fr", "rf", 6), // r before f + ("Fr", "rf", 7), // f case not tracked, r before f + ("fR", "Rf", 8), // r before f + ("FR", "Rf", 9), // f case not tracked, r before f + ("rf", "rf", 10), + ("rF", "rf", 11), // f case not tracked + ("Rf", "Rf", 12), + ("RF", "Rf", 13), // f case not tracked // bytestrings - ("b", "b"), - ("B", "b"), // b case - ("br", "rb"), // r before b - ("Br", "rb"), // b case, r before b - ("bR", "Rb"), // r before b - ("BR", "Rb"), // b case, r before b - ("rb", "rb"), - ("rB", "rb"), // b case - ("Rb", "Rb"), - ("RB", "Rb"), // b case - ]; - let quotes = ["\"", "'", "\"\"\"", "'''"]; - for (inp, out) in string_prefixes { - for q in quotes { - let input = format!("{inp}{q}hello{q}"); - let output = format!("{out}{q}hello{q}"); - assert_eq!(round_trip(&input), output); - - // variants with f-string patterns - let input = format!("{inp}{q}{{hello}} {{world}}{q}"); - let output = format!("{out}{q}{{hello}} {{world}}{q}"); - assert_eq!(round_trip(&input), output); - } - } + ("b", "b", 14), + ("B", "b", 15), // b case + ("br", "rb", 16), // r before b + ("Br", "rb", 17), // b case, r before b + ("bR", "Rb", 18), // r before b + ("BR", "Rb", 19), // b case, r before b + ("rb", "rb", 20), + ("rB", "rb", 21), // b case + ("Rb", "Rb", 22), + ("RB", "Rb", 23), // b case + ], + [("\"", 0), ("'",1), ("\"\"\"", 2), ("'''", 3)], + ["hello", "{hello} {world}"] + )] + fn prefix_quotes((inp, out, _id): (&str, &str, u8), (quote, _id2): (&str, u8), base: &str) { + let input = format!("{inp}{quote}{base}{quote}"); + let output = format!("{out}{quote}{base}{quote}"); + assert_eq!(round_trip(&input), output); } #[test] From 759cb6402f92c926c46e723177900c74bf45ab9b Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Wed, 29 Jan 2025 18:41:42 -0500 Subject: [PATCH 11/28] use TripleQuoted enum instead of bool Co-authored-by: Alex Waygood --- .../src/types/display.rs | 4 +- crates/ruff_python_codegen/src/generator.rs | 6 +-- crates/ruff_python_literal/src/escape.rs | 44 +++++++++++++++---- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types/display.rs b/crates/red_knot_python_semantic/src/types/display.rs index ac02e57b24c19..014f3e5571add 100644 --- a/crates/red_knot_python_semantic/src/types/display.rs +++ b/crates/red_knot_python_semantic/src/types/display.rs @@ -4,7 +4,7 @@ use std::fmt::{self, Display, Formatter, Write}; use ruff_db::display::FormatterJoinExtension; use ruff_python_ast::str::Quote; -use ruff_python_literal::escape::AsciiEscape; +use ruff_python_literal::escape::{AsciiEscape, TripleQuoted}; use crate::types::class_base::ClassBase; use crate::types::{ @@ -98,7 +98,7 @@ impl Display for DisplayRepresentation<'_> { let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db).as_ref(), Quote::Double); - escape.bytes_repr(false).write(f) + escape.bytes_repr(TripleQuoted::No).write(f) } Type::SliceLiteral(slice) => { f.write_str("slice[")?; diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 1f6d5a1f8f978..eb2b8337184a3 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -9,7 +9,7 @@ use ruff_python_ast::{ TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, WithItem, }; use ruff_python_ast::{ParameterWithDefault, TypeParams}; -use ruff_python_literal::escape::{AsciiEscape, Escape, UnicodeEscape}; +use ruff_python_literal::escape::{AsciiEscape, Escape, TripleQuoted, UnicodeEscape}; use ruff_source_file::LineEnding; use super::stylist::{Indentation, Stylist}; @@ -156,7 +156,7 @@ impl<'a> Generator<'a> { self.buffer.reserve(len); } escape - .bytes_repr(flags.is_triple_quoted()) + .bytes_repr(TripleQuoted::from(flags)) .write(&mut self.buffer) .expect("Writing to a String buffer should never fail"); } @@ -185,7 +185,7 @@ impl<'a> Generator<'a> { self.buffer.reserve(len); } escape - .str_repr(flags.is_triple_quoted()) + .str_repr(TripleQuoted::from(flags)) .write(&mut self.buffer) .expect("Writing to a String buffer should never fail"); } diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 8a574d1b49171..901f31e98f816 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::str::Quote; +use ruff_python_ast::{str::Quote, StringFlags}; pub struct EscapeLayout { pub quote: Quote, @@ -23,6 +23,32 @@ pub trait Escape { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum TripleQuoted { + Yes, + No, +} + +impl TripleQuoted { + #[must_use] + pub fn is_yes(&self) -> bool { + matches!(self, Self::Yes) + } +} + +impl From for TripleQuoted +where + F: StringFlags, +{ + fn from(value: F) -> Self { + if value.is_triple_quoted() { + Self::Yes + } else { + Self::No + } + } +} + /// Returns the outer quotes to use and the number of quotes that need to be /// escaped. pub(crate) const fn choose_quote( @@ -60,7 +86,7 @@ impl<'a> UnicodeEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn str_repr<'r>(&'a self, triple_quote: bool) -> StrRepr<'r, 'a> { + pub fn str_repr<'r>(&'a self, triple_quote: TripleQuoted) -> StrRepr<'r, 'a> { StrRepr { escape: self, triple_quote, @@ -70,20 +96,20 @@ impl<'a> UnicodeEscape<'a> { pub struct StrRepr<'r, 'a> { escape: &'r UnicodeEscape<'a>, - triple_quote: bool, + triple_quote: TripleQuoted, } impl StrRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { let quote = self.escape.layout().quote.as_char(); formatter.write_char(quote)?; - if self.triple_quote { + if self.triple_quote.is_yes() { formatter.write_char(quote)?; formatter.write_char(quote)?; } self.escape.write_body(formatter)?; formatter.write_char(quote)?; - if self.triple_quote { + if self.triple_quote.is_yes() { formatter.write_char(quote)?; formatter.write_char(quote)?; } @@ -259,7 +285,7 @@ impl<'a> AsciiEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn bytes_repr<'r>(&'a self, triple_quote: bool) -> BytesRepr<'r, 'a> { + pub fn bytes_repr<'r>(&'a self, triple_quote: TripleQuoted) -> BytesRepr<'r, 'a> { BytesRepr { escape: self, triple_quote, @@ -380,7 +406,7 @@ impl Escape for AsciiEscape<'_> { pub struct BytesRepr<'r, 'a> { escape: &'r AsciiEscape<'a>, - triple_quote: bool, + triple_quote: TripleQuoted, } impl BytesRepr<'_, '_> { @@ -388,13 +414,13 @@ impl BytesRepr<'_, '_> { let quote = self.escape.layout().quote.as_char(); formatter.write_char('b')?; formatter.write_char(quote)?; - if self.triple_quote { + if self.triple_quote.is_yes() { formatter.write_char(quote)?; formatter.write_char(quote)?; } self.escape.write_body(formatter)?; formatter.write_char(quote)?; - if self.triple_quote { + if self.triple_quote.is_yes() { formatter.write_char(quote)?; formatter.write_char(quote)?; } From 5ae157cf24fa6dd248c24bccdae06cb8cc8f5922 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 08:48:01 -0500 Subject: [PATCH 12/28] remove redundant quote tests --- crates/ruff_python_codegen/src/generator.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index eb2b8337184a3..f006794a03b1a 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1741,20 +1741,6 @@ class Foo: assert_eq!(round_trip(r#""he\"llo""#), r#"'he"llo'"#); assert_eq!(round_trip(r#"f"abc{'def'}{1}""#), r#"f"abc{'def'}{1}""#); assert_round_trip!(r#"f'abc{"def"}{1}'"#); - // triple double quotes should be preserved for all string types - assert_round_trip!(r#""""hello""""#); - assert_round_trip!(r#"u"""hello""""#); - assert_round_trip!(r#"r"""hello""""#); - assert_round_trip!(r#"b"""hello""""#); - assert_round_trip!(r#"f"""hello""""#); - assert_round_trip!(r#"f"""{hello}""""#); - // same for triple single quotes - assert_round_trip!(r#"'''hello'''"#); - assert_round_trip!(r#"u'''hello'''"#); - assert_round_trip!(r#"r'''hello'''"#); - assert_round_trip!(r#"b'''hello'''"#); - assert_round_trip!(r#"f'''hello'''"#); - assert_round_trip!(r#"f'''{hello}'''"#); } /// test all of the valid string literal prefix and quote combinations from From 55379b74bf361b523c5f3bd020a6a3b4a5a40651 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 08:49:58 -0500 Subject: [PATCH 13/28] add nested quote test for bytestring Co-authored-by: Alex Waygood --- crates/ruff_python_codegen/src/generator.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index f006794a03b1a..fcfaf3938e529 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1739,6 +1739,7 @@ class Foo: assert_round_trip!(r#"f"hello""#); assert_eq!(round_trip(r#"("abc" "def" "ghi")"#), r#""abc" "def" "ghi""#); assert_eq!(round_trip(r#""he\"llo""#), r#"'he"llo'"#); + assert_eq!(round_trip(r#"b"he\"llo""#), r#"b'he"llo'"#); assert_eq!(round_trip(r#"f"abc{'def'}{1}""#), r#"f"abc{'def'}{1}""#); assert_round_trip!(r#"f'abc{"def"}{1}'"#); } From 0550ac1dd7120da68d6860d7cb35f7164d2995b6 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 08:50:48 -0500 Subject: [PATCH 14/28] mark is_yes const Co-authored-by: Alex Waygood --- crates/ruff_python_literal/src/escape.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 901f31e98f816..f94e927947393 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -31,7 +31,7 @@ pub enum TripleQuoted { impl TripleQuoted { #[must_use] - pub fn is_yes(&self) -> bool { + pub const fn is_yes(&self) -> bool { matches!(self, Self::Yes) } } From 6183c74d297957973f12b1da1e502a154a284bef Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 30 Jan 2025 14:39:04 +0000 Subject: [PATCH 15/28] prototype making the `TripleQuoted` enum more central to the API --- .../src/types/display.rs | 6 +- .../rules/split_static_string.rs | 6 +- crates/ruff_python_ast/src/nodes.rs | 156 ++++++++---------- crates/ruff_python_ast/src/str.rs | 18 ++ crates/ruff_python_codegen/src/generator.rs | 6 +- .../src/string/implicit.rs | 4 +- .../ruff_python_formatter/src/string/mod.rs | 10 +- .../src/string/normalize.rs | 15 +- crates/ruff_python_literal/src/escape.rs | 74 +++------ crates/ruff_python_parser/src/token.rs | 12 +- 10 files changed, 140 insertions(+), 167 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types/display.rs b/crates/red_knot_python_semantic/src/types/display.rs index 014f3e5571add..23b6395ca4e9a 100644 --- a/crates/red_knot_python_semantic/src/types/display.rs +++ b/crates/red_knot_python_semantic/src/types/display.rs @@ -3,8 +3,8 @@ use std::fmt::{self, Display, Formatter, Write}; use ruff_db::display::FormatterJoinExtension; -use ruff_python_ast::str::Quote; -use ruff_python_literal::escape::{AsciiEscape, TripleQuoted}; +use ruff_python_ast::str::{Quote, TripleQuotes}; +use ruff_python_literal::escape::AsciiEscape; use crate::types::class_base::ClassBase; use crate::types::{ @@ -98,7 +98,7 @@ impl Display for DisplayRepresentation<'_> { let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db).as_ref(), Quote::Double); - escape.bytes_repr(TripleQuoted::No).write(f) + escape.bytes_repr(TripleQuotes::No).write(f) } Type::SliceLiteral(slice) => { f.write_str("slice[")?; diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs index 8f0d6d6082d62..fb2dbd4c52220 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs @@ -3,8 +3,8 @@ use std::cmp::Ordering; use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, ViolationMetadata}; use ruff_python_ast::{ - Expr, ExprCall, ExprContext, ExprList, ExprUnaryOp, StringLiteral, StringLiteralFlags, - StringLiteralValue, UnaryOp, + str::TripleQuotes, Expr, ExprCall, ExprContext, ExprList, ExprUnaryOp, StringLiteral, + StringLiteralFlags, StringLiteralValue, UnaryOp, }; use ruff_text_size::{Ranged, TextRange}; @@ -133,7 +133,7 @@ fn construct_replacement(elts: &[&str], flags: StringLiteralFlags) -> Expr { // itemC // """.split() # -> ["""itemA""", """itemB""", """itemC"""] // ``` - flags: flags.without_triple_quotes(), + flags: flags.with_triple_quotes_set_to(TripleQuotes::No), }) }) .collect(), diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 57773bb7af001..dd804ae8a20d4 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -14,6 +14,7 @@ use itertools::Itertools; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use crate::name::Name; +use crate::str::TripleQuotes; use crate::{ int, str::Quote, @@ -981,25 +982,24 @@ pub trait StringFlags: Copy { /// Does the string use single or double quotes in its opener and closer? fn quote_style(self) -> Quote; - /// Is the string triple-quoted, i.e., - /// does it begin and end with three consecutive quote characters? - fn is_triple_quoted(self) -> bool; + fn triple_quotes(self) -> TripleQuotes; fn prefix(self) -> AnyStringPrefix; + /// Is the string triple-quoted, i.e., + /// does it begin and end with three consecutive quote characters? + fn is_triple_quoted(self) -> bool { + self.triple_quotes().is_yes() + } + /// A `str` representation of the quotes used to start and close. /// This does not include any prefixes the string has in its opener. fn quote_str(self) -> &'static str { - if self.is_triple_quoted() { - match self.quote_style() { - Quote::Single => "'''", - Quote::Double => r#"""""#, - } - } else { - match self.quote_style() { - Quote::Single => "'", - Quote::Double => "\"", - } + match (self.triple_quotes(), self.quote_style()) { + (TripleQuotes::Yes, Quote::Single) => "'''", + (TripleQuotes::Yes, Quote::Double) => r#"""""#, + (TripleQuotes::No, Quote::Single) => "'", + (TripleQuotes::No, Quote::Double) => "\"", } } @@ -1097,14 +1097,9 @@ impl FStringFlags { } #[must_use] - pub fn with_triple_quotes(mut self) -> Self { - self.0 |= FStringFlagsInner::TRIPLE_QUOTED; - self - } - - #[must_use] - pub fn without_triple_quotes(mut self) -> Self { - self.0.remove(FStringFlagsInner::TRIPLE_QUOTED); + pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + self.0 + .set(FStringFlagsInner::TRIPLE_QUOTED, triple_quotes.is_yes()); self } @@ -1138,8 +1133,12 @@ impl StringFlags for FStringFlags { /// Return `true` if the f-string is triple-quoted, i.e., /// it begins and ends with three consecutive quote characters. /// For example: `f"""{bar}"""` - fn is_triple_quoted(self) -> bool { - self.0.contains(FStringFlagsInner::TRIPLE_QUOTED) + fn triple_quotes(self) -> TripleQuotes { + if self.0.contains(FStringFlagsInner::TRIPLE_QUOTED) { + TripleQuotes::Yes + } else { + TripleQuotes::No + } } /// Return the quoting style (single or double quotes) @@ -1483,14 +1482,11 @@ impl StringLiteralFlags { } #[must_use] - pub fn with_triple_quotes(mut self) -> Self { - self.0 |= StringLiteralFlagsInner::TRIPLE_QUOTED; - self - } - - #[must_use] - pub fn without_triple_quotes(mut self) -> Self { - self.0.remove(StringLiteralFlagsInner::TRIPLE_QUOTED); + pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + self.0.set( + StringLiteralFlagsInner::TRIPLE_QUOTED, + triple_quotes.is_yes(), + ); self } @@ -1562,8 +1558,12 @@ impl StringFlags for StringLiteralFlags { /// Return `true` if the string is triple-quoted, i.e., /// it begins and ends with three consecutive quote characters. /// For example: `"""bar"""` - fn is_triple_quoted(self) -> bool { - self.0.contains(StringLiteralFlagsInner::TRIPLE_QUOTED) + fn triple_quotes(self) -> TripleQuotes { + if self.0.contains(StringLiteralFlagsInner::TRIPLE_QUOTED) { + TripleQuotes::Yes + } else { + TripleQuotes::No + } } fn prefix(self) -> AnyStringPrefix { @@ -1878,14 +1878,11 @@ impl BytesLiteralFlags { } #[must_use] - pub fn with_triple_quotes(mut self) -> Self { - self.0 |= BytesLiteralFlagsInner::TRIPLE_QUOTED; - self - } - - #[must_use] - pub fn without_triple_quotes(mut self) -> Self { - self.0.remove(BytesLiteralFlagsInner::TRIPLE_QUOTED); + pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + self.0.set( + BytesLiteralFlagsInner::TRIPLE_QUOTED, + triple_quotes.is_yes(), + ); self } @@ -1928,8 +1925,12 @@ impl StringFlags for BytesLiteralFlags { /// Return `true` if the bytestring is triple-quoted, i.e., /// it begins and ends with three consecutive quote characters. /// For example: `b"""{bar}"""` - fn is_triple_quoted(self) -> bool { - self.0.contains(BytesLiteralFlagsInner::TRIPLE_QUOTED) + fn triple_quotes(self) -> TripleQuotes { + if self.0.contains(BytesLiteralFlagsInner::TRIPLE_QUOTED) { + TripleQuotes::Yes + } else { + TripleQuotes::No + } } /// Return the quoting style (single or double quotes) @@ -2091,13 +2092,11 @@ impl AnyStringFlags { self } - pub fn new(prefix: AnyStringPrefix, quotes: Quote, triple_quoted: bool) -> Self { - let new = Self::default().with_prefix(prefix).with_quote_style(quotes); - if triple_quoted { - new.with_triple_quotes() - } else { - new - } + pub fn new(prefix: AnyStringPrefix, quotes: Quote, triple_quotes: TripleQuotes) -> Self { + Self::default() + .with_prefix(prefix) + .with_quote_style(quotes) + .with_triple_quotes_set_to(triple_quotes) } /// Does the string have a `u` or `U` prefix? @@ -2132,14 +2131,9 @@ impl AnyStringFlags { } #[must_use] - pub fn with_triple_quotes(mut self) -> Self { - self.0 |= AnyStringFlagsInner::TRIPLE_QUOTED; - self - } - - #[must_use] - pub fn without_triple_quotes(mut self) -> Self { - self.0.remove(AnyStringFlagsInner::TRIPLE_QUOTED); + pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + self.0 + .set(AnyStringFlagsInner::TRIPLE_QUOTED, triple_quotes.is_yes()); self } } @@ -2154,10 +2148,12 @@ impl StringFlags for AnyStringFlags { } } - /// Is the string triple-quoted, i.e., - /// does it begin and end with three consecutive quote characters? - fn is_triple_quoted(self) -> bool { - self.0.contains(AnyStringFlagsInner::TRIPLE_QUOTED) + fn triple_quotes(self) -> TripleQuotes { + if self.0.contains(AnyStringFlagsInner::TRIPLE_QUOTED) { + TripleQuotes::Yes + } else { + TripleQuotes::No + } } fn prefix(self) -> AnyStringPrefix { @@ -2217,14 +2213,10 @@ impl From for StringLiteralFlags { value.prefix() ) }; - let new = StringLiteralFlags::empty() + StringLiteralFlags::empty() .with_quote_style(value.quote_style()) - .with_prefix(prefix); - if value.is_triple_quoted() { - new.with_triple_quotes() - } else { - new - } + .with_prefix(prefix) + .with_triple_quotes_set_to(value.triple_quotes()) } } @@ -2233,7 +2225,7 @@ impl From for AnyStringFlags { Self::new( AnyStringPrefix::Regular(value.prefix()), value.quote_style(), - value.is_triple_quoted(), + value.triple_quotes(), ) } } @@ -2246,14 +2238,10 @@ impl From for BytesLiteralFlags { value.prefix() ) }; - let new = BytesLiteralFlags::empty() + BytesLiteralFlags::empty() .with_quote_style(value.quote_style()) - .with_prefix(bytestring_prefix); - if value.is_triple_quoted() { - new.with_triple_quotes() - } else { - new - } + .with_prefix(bytestring_prefix) + .with_triple_quotes_set_to(value.triple_quotes()) } } @@ -2262,7 +2250,7 @@ impl From for AnyStringFlags { Self::new( AnyStringPrefix::Bytes(value.prefix()), value.quote_style(), - value.is_triple_quoted(), + value.triple_quotes(), ) } } @@ -2275,14 +2263,10 @@ impl From for FStringFlags { value.prefix() ) }; - let new = FStringFlags::empty() + FStringFlags::empty() .with_quote_style(value.quote_style()) - .with_prefix(fstring_prefix); - if value.is_triple_quoted() { - new.with_triple_quotes() - } else { - new - } + .with_prefix(fstring_prefix) + .with_triple_quotes_set_to(value.triple_quotes()) } } @@ -2291,7 +2275,7 @@ impl From for AnyStringFlags { Self::new( AnyStringPrefix::Format(value.prefix()), value.quote_style(), - value.is_triple_quoted(), + value.triple_quotes(), ) } } diff --git a/crates/ruff_python_ast/src/str.rs b/crates/ruff_python_ast/src/str.rs index 33a9bf0d0cada..5a8dd1093e3b5 100644 --- a/crates/ruff_python_ast/src/str.rs +++ b/crates/ruff_python_ast/src/str.rs @@ -68,6 +68,24 @@ impl TryFrom for Quote { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum TripleQuotes { + Yes, + No, +} + +impl TripleQuotes { + #[must_use] + pub const fn is_yes(self) -> bool { + matches!(self, Self::Yes) + } + + #[must_use] + pub const fn is_no(self) -> bool { + matches!(self, Self::No) + } +} + /// Includes all permutations of `r`, `u`, `f`, and `fr` (`ur` is invalid, as is `uf`). This /// includes all possible orders, and all possible casings, for both single and triple quotes. /// diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index eb2b8337184a3..097a277a0001a 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -9,7 +9,7 @@ use ruff_python_ast::{ TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, WithItem, }; use ruff_python_ast::{ParameterWithDefault, TypeParams}; -use ruff_python_literal::escape::{AsciiEscape, Escape, TripleQuoted, UnicodeEscape}; +use ruff_python_literal::escape::{AsciiEscape, Escape, UnicodeEscape}; use ruff_source_file::LineEnding; use super::stylist::{Indentation, Stylist}; @@ -156,7 +156,7 @@ impl<'a> Generator<'a> { self.buffer.reserve(len); } escape - .bytes_repr(TripleQuoted::from(flags)) + .bytes_repr(flags.triple_quotes()) .write(&mut self.buffer) .expect("Writing to a String buffer should never fail"); } @@ -185,7 +185,7 @@ impl<'a> Generator<'a> { self.buffer.reserve(len); } escape - .str_repr(TripleQuoted::from(flags)) + .str_repr(flags.triple_quotes()) .write(&mut self.buffer) .expect("Writing to a String buffer should never fail"); } diff --git a/crates/ruff_python_formatter/src/string/implicit.rs b/crates/ruff_python_formatter/src/string/implicit.rs index 88061d0792aff..b152d79ec3783 100644 --- a/crates/ruff_python_formatter/src/string/implicit.rs +++ b/crates/ruff_python_formatter/src/string/implicit.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use ruff_formatter::{format_args, write, FormatContext}; -use ruff_python_ast::str::Quote; +use ruff_python_ast::str::{Quote, TripleQuotes}; use ruff_python_ast::str_prefix::{ AnyStringPrefix, ByteStringPrefix, FStringPrefix, StringLiteralPrefix, }; @@ -230,7 +230,7 @@ impl<'a> FormatImplicitConcatenatedStringFlat<'a> { } }; - Some(AnyStringFlags::new(prefix, quote, false)) + Some(AnyStringFlags::new(prefix, quote, TripleQuotes::No)) } if !string.is_implicit_concatenated() { diff --git a/crates/ruff_python_formatter/src/string/mod.rs b/crates/ruff_python_formatter/src/string/mod.rs index ca4e59fda350c..5e2183be3a864 100644 --- a/crates/ruff_python_formatter/src/string/mod.rs +++ b/crates/ruff_python_formatter/src/string/mod.rs @@ -1,6 +1,6 @@ use memchr::memchr2; pub(crate) use normalize::{normalize_string, NormalizedString, StringNormalizer}; -use ruff_python_ast::str::Quote; +use ruff_python_ast::str::{Quote, TripleQuotes}; use ruff_python_ast::StringLikePart; use ruff_python_ast::{ self as ast, @@ -95,11 +95,11 @@ impl StringLikeExtensions for ast::StringLike<'_> { fn contains_line_break_or_comments( elements: &ast::FStringElements, context: &PyFormatContext, - is_triple_quoted: bool, + triple_quotes: TripleQuotes, ) -> bool { elements.iter().any(|element| match element { ast::FStringElement::Literal(literal) => { - is_triple_quoted + triple_quotes.is_yes() && context.source().contains_line_break(literal.range()) } ast::FStringElement::Expression(expression) => { @@ -119,7 +119,7 @@ impl StringLikeExtensions for ast::StringLike<'_> { contains_line_break_or_comments( &spec.elements, context, - is_triple_quoted, + triple_quotes, ) }) || expression.debug_text.as_ref().is_some_and(|debug_text| { @@ -134,7 +134,7 @@ impl StringLikeExtensions for ast::StringLike<'_> { contains_line_break_or_comments( &f_string.elements, context, - f_string.flags.is_triple_quoted(), + f_string.flags.triple_quotes(), ) } }) diff --git a/crates/ruff_python_formatter/src/string/normalize.rs b/crates/ruff_python_formatter/src/string/normalize.rs index f15fe896418a9..0c3e0cb6f3975 100644 --- a/crates/ruff_python_formatter/src/string/normalize.rs +++ b/crates/ruff_python_formatter/src/string/normalize.rs @@ -5,8 +5,9 @@ use std::iter::FusedIterator; use ruff_formatter::FormatContext; use ruff_python_ast::visitor::source_order::SourceOrderVisitor; use ruff_python_ast::{ - str::Quote, AnyStringFlags, BytesLiteral, FString, FStringElement, FStringElements, - FStringFlags, StringFlags, StringLikePart, StringLiteral, + str::{Quote, TripleQuotes}, + AnyStringFlags, BytesLiteral, FString, FStringElement, FStringElements, FStringFlags, + StringFlags, StringLikePart, StringLiteral, }; use ruff_text_size::{Ranged, TextRange, TextSlice}; @@ -273,7 +274,7 @@ impl QuoteMetadata { pub(crate) fn from_str(text: &str, flags: AnyStringFlags, preferred_quote: Quote) -> Self { let kind = if flags.is_raw_string() { - QuoteMetadataKind::raw(text, preferred_quote, flags.is_triple_quoted()) + QuoteMetadataKind::raw(text, preferred_quote, flags.triple_quotes()) } else if flags.is_triple_quoted() { QuoteMetadataKind::triple_quoted(text, preferred_quote) } else { @@ -528,7 +529,7 @@ impl QuoteMetadataKind { /// Computes if a raw string uses the preferred quote. If it does, then it's not possible /// to change the quote style because it would require escaping which isn't possible in raw strings. - fn raw(text: &str, preferred: Quote, triple_quoted: bool) -> Self { + fn raw(text: &str, preferred: Quote, triple_quotes: TripleQuotes) -> Self { let mut chars = text.chars().peekable(); let preferred_quote_char = preferred.as_char(); @@ -540,7 +541,7 @@ impl QuoteMetadataKind { } // `"` or `'` Some(c) if c == preferred_quote_char => { - if !triple_quoted { + if triple_quotes.is_no() { break true; } @@ -1057,7 +1058,7 @@ mod tests { use std::borrow::Cow; use ruff_python_ast::{ - str::Quote, + str::{Quote, TripleQuotes}, str_prefix::{AnyStringPrefix, ByteStringPrefix}, AnyStringFlags, }; @@ -1086,7 +1087,7 @@ mod tests { AnyStringFlags::new( AnyStringPrefix::Bytes(ByteStringPrefix::Regular), Quote::Double, - false, + TripleQuotes::No, ), false, ); diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 901f31e98f816..534b7f4f058f1 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -1,4 +1,7 @@ -use ruff_python_ast::{str::Quote, StringFlags}; +use ruff_python_ast::{ + str::{Quote, TripleQuotes}, + BytesLiteralFlags, StringFlags, StringLiteralFlags, +}; pub struct EscapeLayout { pub quote: Quote, @@ -23,32 +26,6 @@ pub trait Escape { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum TripleQuoted { - Yes, - No, -} - -impl TripleQuoted { - #[must_use] - pub fn is_yes(&self) -> bool { - matches!(self, Self::Yes) - } -} - -impl From for TripleQuoted -where - F: StringFlags, -{ - fn from(value: F) -> Self { - if value.is_triple_quoted() { - Self::Yes - } else { - Self::No - } - } -} - /// Returns the outer quotes to use and the number of quotes that need to be /// escaped. pub(crate) const fn choose_quote( @@ -86,7 +63,7 @@ impl<'a> UnicodeEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn str_repr<'r>(&'a self, triple_quote: TripleQuoted) -> StrRepr<'r, 'a> { + pub fn str_repr<'r>(&'a self, triple_quote: TripleQuotes) -> StrRepr<'r, 'a> { StrRepr { escape: self, triple_quote, @@ -96,23 +73,17 @@ impl<'a> UnicodeEscape<'a> { pub struct StrRepr<'r, 'a> { escape: &'r UnicodeEscape<'a>, - triple_quote: TripleQuoted, + triple_quote: TripleQuotes, } impl StrRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { - let quote = self.escape.layout().quote.as_char(); - formatter.write_char(quote)?; - if self.triple_quote.is_yes() { - formatter.write_char(quote)?; - formatter.write_char(quote)?; - } + let flags = StringLiteralFlags::empty() + .with_quote_style(self.escape.layout().quote) + .with_triple_quotes_set_to(self.triple_quote); + formatter.write_str(flags.quote_str())?; self.escape.write_body(formatter)?; - formatter.write_char(quote)?; - if self.triple_quote.is_yes() { - formatter.write_char(quote)?; - formatter.write_char(quote)?; - } + formatter.write_str(flags.quote_str())?; Ok(()) } @@ -285,10 +256,10 @@ impl<'a> AsciiEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn bytes_repr<'r>(&'a self, triple_quote: TripleQuoted) -> BytesRepr<'r, 'a> { + pub fn bytes_repr<'r>(&'a self, triple_quotes: TripleQuotes) -> BytesRepr<'r, 'a> { BytesRepr { escape: self, - triple_quote, + triple_quotes, } } } @@ -406,24 +377,19 @@ impl Escape for AsciiEscape<'_> { pub struct BytesRepr<'r, 'a> { escape: &'r AsciiEscape<'a>, - triple_quote: TripleQuoted, + triple_quotes: TripleQuotes, } impl BytesRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { - let quote = self.escape.layout().quote.as_char(); + let flags = BytesLiteralFlags::empty() + .with_quote_style(self.escape.layout().quote) + .with_triple_quotes_set_to(self.triple_quotes); + formatter.write_char('b')?; - formatter.write_char(quote)?; - if self.triple_quote.is_yes() { - formatter.write_char(quote)?; - formatter.write_char(quote)?; - } + formatter.write_str(flags.quote_str())?; self.escape.write_body(formatter)?; - formatter.write_char(quote)?; - if self.triple_quote.is_yes() { - formatter.write_char(quote)?; - formatter.write_char(quote)?; - } + formatter.write_str(flags.quote_str())?; Ok(()) } diff --git a/crates/ruff_python_parser/src/token.rs b/crates/ruff_python_parser/src/token.rs index 9c240f4964e5b..ecda19730a2d5 100644 --- a/crates/ruff_python_parser/src/token.rs +++ b/crates/ruff_python_parser/src/token.rs @@ -10,7 +10,7 @@ use std::fmt; use bitflags::bitflags; use ruff_python_ast::name::Name; -use ruff_python_ast::str::Quote; +use ruff_python_ast::str::{Quote, TripleQuotes}; use ruff_python_ast::str_prefix::{ AnyStringPrefix, ByteStringPrefix, FStringPrefix, StringLiteralPrefix, }; @@ -718,8 +718,12 @@ impl StringFlags for TokenFlags { } } - fn is_triple_quoted(self) -> bool { - self.intersects(TokenFlags::TRIPLE_QUOTED_STRING) + fn triple_quotes(self) -> TripleQuotes { + if self.intersects(TokenFlags::TRIPLE_QUOTED_STRING) { + TripleQuotes::Yes + } else { + TripleQuotes::No + } } fn prefix(self) -> AnyStringPrefix { @@ -769,7 +773,7 @@ impl TokenFlags { /// Converts this type to [`AnyStringFlags`], setting the equivalent flags. pub(crate) fn as_any_string_flags(self) -> AnyStringFlags { - AnyStringFlags::new(self.prefix(), self.quote_style(), self.is_triple_quoted()) + AnyStringFlags::new(self.prefix(), self.quote_style(), self.triple_quotes()) } } From 718fb8294aa2f972d4eb0a5a21f842efd5d62138 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 10:24:22 -0500 Subject: [PATCH 16/28] update doc links --- crates/ruff_python_ast/src/nodes.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index dd804ae8a20d4..db45b5b3df1a7 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1078,7 +1078,7 @@ pub struct FStringFlags(FStringFlagsInner); impl FStringFlags { /// Construct a new [`FStringFlags`] with **no flags set**. /// - /// See [`FStringFlags::with_quote_style`], [`FStringFlags::with_triple_quotes`], and + /// See [`FStringFlags::with_quote_style`], [`FStringFlags::with_triple_quotes_set_to`], and /// [`FStringFlags::with_prefix`] for ways of setting the quote style (single or double), /// enabling triple quotes, and adding prefixes (such as `r`), respectively. /// @@ -1463,9 +1463,10 @@ pub struct StringLiteralFlags(StringLiteralFlagsInner); impl StringLiteralFlags { /// Construct a new [`StringLiteralFlags`] with **no flags set**. /// - /// See [`StringLiteralFlags::with_quote_style`], [`StringLiteralFlags::with_triple_quotes`], - /// and [`StringLiteralFlags::with_prefix`] for ways of setting the quote style (single or - /// double), enabling triple quotes, and adding prefixes (such as `r` or `u`), respectively. + /// See [`StringLiteralFlags::with_quote_style`], + /// [`StringLiteralFlags::with_triple_quotes_set_to`], and [`StringLiteralFlags::with_prefix`] + /// for ways of setting the quote style (single or double), enabling triple quotes, and adding + /// prefixes (such as `r` or `u`), respectively. /// /// See the documentation for [`StringLiteralFlags`] for additional caveats on this constructor, /// and situations in which alternative ways to construct this struct should be used, especially @@ -1859,9 +1860,10 @@ pub struct BytesLiteralFlags(BytesLiteralFlagsInner); impl BytesLiteralFlags { /// Construct a new [`BytesLiteralFlags`] with **no flags set**. /// - /// See [`BytesLiteralFlags::with_quote_style`], [`BytesLiteralFlags::with_triple_quotes`], and - /// [`BytesLiteralFlags::with_prefix`] for ways of setting the quote style (single or double), - /// enabling triple quotes, and adding prefixes (such as `r`), respectively. + /// See [`BytesLiteralFlags::with_quote_style`], + /// [`BytesLiteralFlags::with_triple_quotes_set_to`], and [`BytesLiteralFlags::with_prefix`] for + /// ways of setting the quote style (single or double), enabling triple quotes, and adding + /// prefixes (such as `r`), respectively. /// /// See the documentation for [`BytesLiteralFlags`] for additional caveats on this constructor, /// and situations in which alternative ways to construct this struct should be used, especially From 073f1e92e2256ab919b243df6f492f94549199b0 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 11:45:56 -0500 Subject: [PATCH 17/28] rename field to triple_quotes Co-authored-by: Alex Waygood --- crates/ruff_python_literal/src/escape.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 534b7f4f058f1..470c11fb43a52 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -63,24 +63,24 @@ impl<'a> UnicodeEscape<'a> { Self::with_preferred_quote(source, Quote::Single) } #[inline] - pub fn str_repr<'r>(&'a self, triple_quote: TripleQuotes) -> StrRepr<'r, 'a> { + pub fn str_repr<'r>(&'a self, triple_quotes: TripleQuotes) -> StrRepr<'r, 'a> { StrRepr { escape: self, - triple_quote, + triple_quotes, } } } pub struct StrRepr<'r, 'a> { escape: &'r UnicodeEscape<'a>, - triple_quote: TripleQuotes, + triple_quotes: TripleQuotes, } impl StrRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { let flags = StringLiteralFlags::empty() .with_quote_style(self.escape.layout().quote) - .with_triple_quotes_set_to(self.triple_quote); + .with_triple_quotes_set_to(self.triple_quotes); formatter.write_str(flags.quote_str())?; self.escape.write_body(formatter)?; formatter.write_str(flags.quote_str())?; From f95a28db19ac3420bc4c6c7da2bf3b16c6238d95 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 12:04:04 -0500 Subject: [PATCH 18/28] add StringFlags::write_string_contents Co-authored-by: Alex Waygood --- crates/ruff_python_ast/src/nodes.rs | 8 ++++++++ crates/ruff_python_codegen/src/generator.rs | 5 ++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index db45b5b3df1a7..663299c5a28ea 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1033,6 +1033,14 @@ pub trait StringFlags: Copy { let quote_str = self.quote_str(); format!("{prefix}{quote_str}{contents}{quote_str}") } + + fn write_string_contents(self, buffer: &mut String, contents: &str) { + let quote_str = self.quote_str(); + buffer.push_str(self.prefix().as_str()); + buffer.push_str(quote_str); + buffer.push_str(contents); + buffer.push_str(quote_str); + } } bitflags! { diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 78642ec7dad76..4727e9009a9fc 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -168,15 +168,14 @@ impl<'a> Generator<'a> { s: &[u8], flags: BytesLiteralFlags, ) -> Result<(), std::str::Utf8Error> { - let body = std::str::from_utf8(s)?; - self.p(&flags.format_string_contents(body)); + flags.write_string_contents(&mut self.buffer, std::str::from_utf8(s)?); Ok(()) } fn p_str_repr(&mut self, s: &str, flags: impl Into) { let flags = flags.into(); if flags.prefix().is_raw() { - self.p(&flags.format_string_contents(s)); + flags.write_string_contents(&mut self.buffer, s); return; } self.p(flags.prefix().as_str()); From 0c55361c62d3517e41ee02cf07e2d545e9ca0f5d Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 13:17:50 -0500 Subject: [PATCH 19/28] expand ascii bytes comment --- crates/ruff_python_codegen/src/generator.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 4727e9009a9fc..b41e10ecf60f9 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -146,8 +146,10 @@ impl<'a> Generator<'a> { } fn p_bytes_repr(&mut self, s: &[u8], flags: BytesLiteralFlags) { - // raw bytes are interpreted without escapes and should all be ascii, but double check - // before writing to self + // raw bytes are interpreted without escapes and should all be ascii (it's a python syntax + // error otherwise), but if this assumption is violated, a `Utf8Error` will be returned from + // `p_raw_bytes`, and we should fall back on the normal escaping behavior instead of + // panicking if flags.prefix().is_raw() && self.p_raw_bytes(s, flags).is_ok() { return; } From dab84a36f5f532e4cd9a6f510c8f14b65a233358 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 14:47:05 -0500 Subject: [PATCH 20/28] remove AnyStringFlags::default --- crates/ruff_python_ast/src/nodes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 663299c5a28ea..41bfaafe054f8 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -2064,7 +2064,7 @@ bitflags! { } } -#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct AnyStringFlags(AnyStringFlagsInner); impl AnyStringFlags { @@ -2103,7 +2103,7 @@ impl AnyStringFlags { } pub fn new(prefix: AnyStringPrefix, quotes: Quote, triple_quotes: TripleQuotes) -> Self { - Self::default() + Self(AnyStringFlagsInner::empty()) .with_prefix(prefix) .with_quote_style(quotes) .with_triple_quotes_set_to(triple_quotes) From 7f6286473346160101fd97129f91bae37fd1f0da Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 14:47:26 -0500 Subject: [PATCH 21/28] use write_string_contents in format_string_contents --- crates/ruff_python_ast/src/nodes.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 41bfaafe054f8..deb25ef05f76c 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1029,9 +1029,10 @@ pub trait StringFlags: Copy { } fn format_string_contents(self, contents: &str) -> String { - let prefix = self.prefix(); - let quote_str = self.quote_str(); - format!("{prefix}{quote_str}{contents}{quote_str}") + let buf_size = self.opener_len().to_usize() + contents.len() + self.closer_len().to_usize(); + let mut buffer = String::with_capacity(buf_size); + self.write_string_contents(&mut buffer, contents); + buffer } fn write_string_contents(self, buffer: &mut String, contents: &str) { From 7eadc7cf626c09d28256a81024cd06e71e8c9417 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 18:11:52 -0500 Subject: [PATCH 22/28] tidy imports Co-authored-by: Alex Waygood --- crates/ruff_python_ast/src/nodes.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index deb25ef05f76c..c8ec81557b254 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -13,11 +13,10 @@ use itertools::Itertools; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; -use crate::name::Name; -use crate::str::TripleQuotes; use crate::{ int, - str::Quote, + name::Name, + str::{Quote, TripleQuotes}, str_prefix::{AnyStringPrefix, ByteStringPrefix, FStringPrefix, StringLiteralPrefix}, ExceptHandler, Expr, FStringElement, LiteralExpressionRef, Pattern, Stmt, TypeParam, }; From 845fe6ad8f9ff3a2e3f3fe9d7ef99b332ea16bf7 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Thu, 30 Jan 2025 18:14:32 -0500 Subject: [PATCH 23/28] move buf_size optimization into write_string_contents Co-authored-by: Alex Waygood --- crates/ruff_python_ast/src/nodes.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index c8ec81557b254..f898441f941f5 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1028,13 +1028,14 @@ pub trait StringFlags: Copy { } fn format_string_contents(self, contents: &str) -> String { - let buf_size = self.opener_len().to_usize() + contents.len() + self.closer_len().to_usize(); - let mut buffer = String::with_capacity(buf_size); + let mut buffer = String::new(); self.write_string_contents(&mut buffer, contents); buffer } fn write_string_contents(self, buffer: &mut String, contents: &str) { + buffer + .reserve(self.opener_len().to_usize() + contents.len() + self.closer_len().to_usize()); let quote_str = self.quote_str(); buffer.push_str(self.prefix().as_str()); buffer.push_str(quote_str); From b7999469235aa79aee9629da45ab0b784ef69259 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Fri, 31 Jan 2025 08:13:01 -0500 Subject: [PATCH 24/28] rename with_triple_quotes_set_to --- .../rules/split_static_string.rs | 2 +- crates/ruff_python_ast/src/nodes.rs | 32 +++++++++---------- crates/ruff_python_literal/src/escape.rs | 4 +-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs index fb2dbd4c52220..f58ed95342fde 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/split_static_string.rs @@ -133,7 +133,7 @@ fn construct_replacement(elts: &[&str], flags: StringLiteralFlags) -> Expr { // itemC // """.split() # -> ["""itemA""", """itemB""", """itemC"""] // ``` - flags: flags.with_triple_quotes_set_to(TripleQuotes::No), + flags: flags.with_triple_quotes(TripleQuotes::No), }) }) .collect(), diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index f898441f941f5..9a45f0ac4349c 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1087,7 +1087,7 @@ pub struct FStringFlags(FStringFlagsInner); impl FStringFlags { /// Construct a new [`FStringFlags`] with **no flags set**. /// - /// See [`FStringFlags::with_quote_style`], [`FStringFlags::with_triple_quotes_set_to`], and + /// See [`FStringFlags::with_quote_style`], [`FStringFlags::with_triple_quotes`], and /// [`FStringFlags::with_prefix`] for ways of setting the quote style (single or double), /// enabling triple quotes, and adding prefixes (such as `r`), respectively. /// @@ -1106,7 +1106,7 @@ impl FStringFlags { } #[must_use] - pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + pub fn with_triple_quotes(mut self, triple_quotes: TripleQuotes) -> Self { self.0 .set(FStringFlagsInner::TRIPLE_QUOTED, triple_quotes.is_yes()); self @@ -1472,10 +1472,9 @@ pub struct StringLiteralFlags(StringLiteralFlagsInner); impl StringLiteralFlags { /// Construct a new [`StringLiteralFlags`] with **no flags set**. /// - /// See [`StringLiteralFlags::with_quote_style`], - /// [`StringLiteralFlags::with_triple_quotes_set_to`], and [`StringLiteralFlags::with_prefix`] - /// for ways of setting the quote style (single or double), enabling triple quotes, and adding - /// prefixes (such as `r` or `u`), respectively. + /// See [`StringLiteralFlags::with_quote_style`], [`StringLiteralFlags::with_triple_quotes`], + /// and [`StringLiteralFlags::with_prefix`] for ways of setting the quote style (single or + /// double), enabling triple quotes, and adding prefixes (such as `r` or `u`), respectively. /// /// See the documentation for [`StringLiteralFlags`] for additional caveats on this constructor, /// and situations in which alternative ways to construct this struct should be used, especially @@ -1492,7 +1491,7 @@ impl StringLiteralFlags { } #[must_use] - pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + pub fn with_triple_quotes(mut self, triple_quotes: TripleQuotes) -> Self { self.0.set( StringLiteralFlagsInner::TRIPLE_QUOTED, triple_quotes.is_yes(), @@ -1869,10 +1868,9 @@ pub struct BytesLiteralFlags(BytesLiteralFlagsInner); impl BytesLiteralFlags { /// Construct a new [`BytesLiteralFlags`] with **no flags set**. /// - /// See [`BytesLiteralFlags::with_quote_style`], - /// [`BytesLiteralFlags::with_triple_quotes_set_to`], and [`BytesLiteralFlags::with_prefix`] for - /// ways of setting the quote style (single or double), enabling triple quotes, and adding - /// prefixes (such as `r`), respectively. + /// See [`BytesLiteralFlags::with_quote_style`], [`BytesLiteralFlags::with_triple_quotes`], and + /// [`BytesLiteralFlags::with_prefix`] for ways of setting the quote style (single or double), + /// enabling triple quotes, and adding prefixes (such as `r`), respectively. /// /// See the documentation for [`BytesLiteralFlags`] for additional caveats on this constructor, /// and situations in which alternative ways to construct this struct should be used, especially @@ -1889,7 +1887,7 @@ impl BytesLiteralFlags { } #[must_use] - pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + pub fn with_triple_quotes(mut self, triple_quotes: TripleQuotes) -> Self { self.0.set( BytesLiteralFlagsInner::TRIPLE_QUOTED, triple_quotes.is_yes(), @@ -2107,7 +2105,7 @@ impl AnyStringFlags { Self(AnyStringFlagsInner::empty()) .with_prefix(prefix) .with_quote_style(quotes) - .with_triple_quotes_set_to(triple_quotes) + .with_triple_quotes(triple_quotes) } /// Does the string have a `u` or `U` prefix? @@ -2142,7 +2140,7 @@ impl AnyStringFlags { } #[must_use] - pub fn with_triple_quotes_set_to(mut self, triple_quotes: TripleQuotes) -> Self { + pub fn with_triple_quotes(mut self, triple_quotes: TripleQuotes) -> Self { self.0 .set(AnyStringFlagsInner::TRIPLE_QUOTED, triple_quotes.is_yes()); self @@ -2227,7 +2225,7 @@ impl From for StringLiteralFlags { StringLiteralFlags::empty() .with_quote_style(value.quote_style()) .with_prefix(prefix) - .with_triple_quotes_set_to(value.triple_quotes()) + .with_triple_quotes(value.triple_quotes()) } } @@ -2252,7 +2250,7 @@ impl From for BytesLiteralFlags { BytesLiteralFlags::empty() .with_quote_style(value.quote_style()) .with_prefix(bytestring_prefix) - .with_triple_quotes_set_to(value.triple_quotes()) + .with_triple_quotes(value.triple_quotes()) } } @@ -2277,7 +2275,7 @@ impl From for FStringFlags { FStringFlags::empty() .with_quote_style(value.quote_style()) .with_prefix(fstring_prefix) - .with_triple_quotes_set_to(value.triple_quotes()) + .with_triple_quotes(value.triple_quotes()) } } diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 470c11fb43a52..5a218dbcfd091 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -80,7 +80,7 @@ impl StrRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { let flags = StringLiteralFlags::empty() .with_quote_style(self.escape.layout().quote) - .with_triple_quotes_set_to(self.triple_quotes); + .with_triple_quotes(self.triple_quotes); formatter.write_str(flags.quote_str())?; self.escape.write_body(formatter)?; formatter.write_str(flags.quote_str())?; @@ -384,7 +384,7 @@ impl BytesRepr<'_, '_> { pub fn write(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { let flags = BytesLiteralFlags::empty() .with_quote_style(self.escape.layout().quote) - .with_triple_quotes_set_to(self.triple_quotes); + .with_triple_quotes(self.triple_quotes); formatter.write_char('b')?; formatter.write_str(flags.quote_str())?; From eef013d2f1ec27d298b92d3fbb8c264a792ce74b Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Mon, 3 Feb 2025 10:00:01 -0500 Subject: [PATCH 25/28] inline p_raw_bytes --- crates/ruff_python_codegen/src/generator.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index b41e10ecf60f9..7eb4fba1acabf 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -150,8 +150,11 @@ impl<'a> Generator<'a> { // error otherwise), but if this assumption is violated, a `Utf8Error` will be returned from // `p_raw_bytes`, and we should fall back on the normal escaping behavior instead of // panicking - if flags.prefix().is_raw() && self.p_raw_bytes(s, flags).is_ok() { - return; + if flags.prefix().is_raw() { + if let Ok(s) = std::str::from_utf8(s) { + flags.write_string_contents(&mut self.buffer, s); + return; + } } let escape = AsciiEscape::with_preferred_quote(s, flags.quote_style()); if let Some(len) = escape.layout().len { @@ -163,17 +166,6 @@ impl<'a> Generator<'a> { .expect("Writing to a String buffer should never fail"); } - /// Returns a [`std::str::Utf8Error`] if `s` is not valid UTF-8, otherwise converts `s` to a - /// `str` and adds it to `self`. - fn p_raw_bytes( - &mut self, - s: &[u8], - flags: BytesLiteralFlags, - ) -> Result<(), std::str::Utf8Error> { - flags.write_string_contents(&mut self.buffer, std::str::from_utf8(s)?); - Ok(()) - } - fn p_str_repr(&mut self, s: &str, flags: impl Into) { let flags = flags.into(); if flags.prefix().is_raw() { From 970565f638fb6fff939e816b38eed77ea866d926 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Mon, 3 Feb 2025 10:23:40 -0500 Subject: [PATCH 26/28] switch to display impl for StringFlags --- .../rules/unnecessary_escaped_quote.rs | 4 +- .../rules/printf_string_formatting.rs | 4 +- crates/ruff_python_ast/src/nodes.rs | 38 ++++++++++++------- crates/ruff_python_codegen/src/generator.rs | 7 +++- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/crates/ruff_linter/src/rules/flake8_quotes/rules/unnecessary_escaped_quote.rs b/crates/ruff_linter/src/rules/flake8_quotes/rules/unnecessary_escaped_quote.rs index d47fd82f3a607..22f5e8eba8f5a 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/rules/unnecessary_escaped_quote.rs +++ b/crates/ruff_linter/src/rules/flake8_quotes/rules/unnecessary_escaped_quote.rs @@ -108,7 +108,9 @@ fn check_string_or_bytes( let mut diagnostic = Diagnostic::new(UnnecessaryEscapedQuote, range); diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - flags.format_string_contents(&unescape_string(contents, opposite_quote_char)), + flags + .display_contents(&unescape_string(contents, opposite_quote_char)) + .to_string(), range, ))); Some(diagnostic) diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs index 36f764de95efe..3917f8bf6b4cb 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs @@ -405,7 +405,9 @@ pub(crate) fn printf_string_formatting( // Convert the `%`-format string to a `.format` string. format_strings.push(( string_literal.range(), - flags.format_string_contents(&percent_to_format(&format_string)), + flags + .display_contents(&percent_to_format(&format_string)) + .to_string(), )); } diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 9a45f0ac4349c..3471776f26475 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1027,20 +1027,30 @@ pub trait StringFlags: Copy { self.quote_len() } - fn format_string_contents(self, contents: &str) -> String { - let mut buffer = String::new(); - self.write_string_contents(&mut buffer, contents); - buffer - } - - fn write_string_contents(self, buffer: &mut String, contents: &str) { - buffer - .reserve(self.opener_len().to_usize() + contents.len() + self.closer_len().to_usize()); - let quote_str = self.quote_str(); - buffer.push_str(self.prefix().as_str()); - buffer.push_str(quote_str); - buffer.push_str(contents); - buffer.push_str(quote_str); + fn display_contents(self, contents: &str) -> DisplayFlags { + DisplayFlags { + prefix: self.prefix(), + quote_str: self.quote_str(), + contents, + } + } +} + +pub struct DisplayFlags<'a> { + prefix: AnyStringPrefix, + quote_str: &'a str, + contents: &'a str, +} + +impl std::fmt::Display for DisplayFlags<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{prefix}{quote}{contents}{quote}", + prefix = self.prefix, + quote = self.quote_str, + contents = self.contents + ) } } diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 7eb4fba1acabf..081a2dbeace25 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1,5 +1,6 @@ //! Generate Python source code from an abstract syntax tree (AST). +use std::fmt::Write; use std::ops::Deref; use ruff_python_ast::{ @@ -152,7 +153,8 @@ impl<'a> Generator<'a> { // panicking if flags.prefix().is_raw() { if let Ok(s) = std::str::from_utf8(s) { - flags.write_string_contents(&mut self.buffer, s); + write!(self.buffer, "{}", flags.display_contents(s)) + .expect("Writing to a String buffer should never fail"); return; } } @@ -169,7 +171,8 @@ impl<'a> Generator<'a> { fn p_str_repr(&mut self, s: &str, flags: impl Into) { let flags = flags.into(); if flags.prefix().is_raw() { - flags.write_string_contents(&mut self.buffer, s); + write!(self.buffer, "{}", flags.display_contents(s)) + .expect("Writing to a String buffer should never fail"); return; } self.p(flags.prefix().as_str()); From 0f83712bd370cbdfb175c95b079f349fc59eb109 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Mon, 3 Feb 2025 10:30:22 -0500 Subject: [PATCH 27/28] add nested quote test case --- .../test/fixtures/flake8_simplify/SIM905.py | 7 + ...ke8_simplify__tests__SIM905_SIM905.py.snap | 1123 +++++++++-------- 2 files changed, 584 insertions(+), 546 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py index ad7da0b856223..e47d1c497004d 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py @@ -9,6 +9,13 @@ itemC """.split() +""" +"itemA" +'itemB' +'''itemC''' +"'itemD'" +""".split() + "a,b,c,d".split(",") "a,b,c,d".split(None) "a,b,c,d".split(",", 1) diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap index b842a85e23e64..e9a47afebc721 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap @@ -11,7 +11,7 @@ SIM905.py:6:1: SIM905 [*] Consider using a list literal instead of `str.split` 10 | | """.split() | |___________^ SIM905 11 | -12 | "a,b,c,d".split(",") +12 | """ | = help: Replace with list literal @@ -26,17 +26,22 @@ SIM905.py:6:1: SIM905 [*] Consider using a list literal instead of `str.split` 10 |-""".split() 6 |+["itemA", "itemB", "itemC"] 11 7 | -12 8 | "a,b,c,d".split(",") -13 9 | "a,b,c,d".split(None) +12 8 | """ +13 9 | "itemA" SIM905.py:12:1: SIM905 [*] Consider using a list literal instead of `str.split` | -10 | """.split() +10 | """.split() 11 | -12 | "a,b,c,d".split(",") - | ^^^^^^^^^^^^^^^^^^^^ SIM905 -13 | "a,b,c,d".split(None) -14 | "a,b,c,d".split(",", 1) +12 | / """ +13 | | "itemA" +14 | | 'itemB' +15 | | '''itemC''' +16 | | "'itemD'" +17 | | """.split() + | |___________^ SIM905 +18 | +19 | "a,b,c,d".split(",") | = help: Replace with list literal @@ -44,802 +49,828 @@ SIM905.py:12:1: SIM905 [*] Consider using a list literal instead of `str.split` 9 9 | itemC 10 10 | """.split() 11 11 | -12 |-"a,b,c,d".split(",") - 12 |+["a", "b", "c", "d"] -13 13 | "a,b,c,d".split(None) -14 14 | "a,b,c,d".split(",", 1) -15 15 | "a,b,c,d".split(None, 1) +12 |-""" +13 |-"itemA" +14 |-'itemB' +15 |-'''itemC''' +16 |-"'itemD'" +17 |-""".split() + 12 |+['"itemA"', "'itemB'", "'''itemC'''", "\"'itemD'\""] +18 13 | +19 14 | "a,b,c,d".split(",") +20 15 | "a,b,c,d".split(None) + +SIM905.py:19:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +17 | """.split() +18 | +19 | "a,b,c,d".split(",") + | ^^^^^^^^^^^^^^^^^^^^ SIM905 +20 | "a,b,c,d".split(None) +21 | "a,b,c,d".split(",", 1) + | + = help: Replace with list literal + +ℹ Safe fix +16 16 | "'itemD'" +17 17 | """.split() +18 18 | +19 |-"a,b,c,d".split(",") + 19 |+["a", "b", "c", "d"] +20 20 | "a,b,c,d".split(None) +21 21 | "a,b,c,d".split(",", 1) +22 22 | "a,b,c,d".split(None, 1) -SIM905.py:13:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:20:1: SIM905 [*] Consider using a list literal instead of `str.split` | -12 | "a,b,c,d".split(",") -13 | "a,b,c,d".split(None) +19 | "a,b,c,d".split(",") +20 | "a,b,c,d".split(None) | ^^^^^^^^^^^^^^^^^^^^^ SIM905 -14 | "a,b,c,d".split(",", 1) -15 | "a,b,c,d".split(None, 1) +21 | "a,b,c,d".split(",", 1) +22 | "a,b,c,d".split(None, 1) | = help: Replace with list literal ℹ Safe fix -10 10 | """.split() -11 11 | -12 12 | "a,b,c,d".split(",") -13 |-"a,b,c,d".split(None) - 13 |+["a,b,c,d"] -14 14 | "a,b,c,d".split(",", 1) -15 15 | "a,b,c,d".split(None, 1) -16 16 | "a,b,c,d".split(sep=",") - -SIM905.py:14:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -12 | "a,b,c,d".split(",") -13 | "a,b,c,d".split(None) -14 | "a,b,c,d".split(",", 1) +17 17 | """.split() +18 18 | +19 19 | "a,b,c,d".split(",") +20 |-"a,b,c,d".split(None) + 20 |+["a,b,c,d"] +21 21 | "a,b,c,d".split(",", 1) +22 22 | "a,b,c,d".split(None, 1) +23 23 | "a,b,c,d".split(sep=",") + +SIM905.py:21:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +19 | "a,b,c,d".split(",") +20 | "a,b,c,d".split(None) +21 | "a,b,c,d".split(",", 1) | ^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -15 | "a,b,c,d".split(None, 1) -16 | "a,b,c,d".split(sep=",") +22 | "a,b,c,d".split(None, 1) +23 | "a,b,c,d".split(sep=",") | = help: Replace with list literal ℹ Safe fix -11 11 | -12 12 | "a,b,c,d".split(",") -13 13 | "a,b,c,d".split(None) -14 |-"a,b,c,d".split(",", 1) - 14 |+["a", "b,c,d"] -15 15 | "a,b,c,d".split(None, 1) -16 16 | "a,b,c,d".split(sep=",") -17 17 | "a,b,c,d".split(sep=None) - -SIM905.py:15:1: SIM905 Consider using a list literal instead of `str.split` - | -13 | "a,b,c,d".split(None) -14 | "a,b,c,d".split(",", 1) -15 | "a,b,c,d".split(None, 1) +18 18 | +19 19 | "a,b,c,d".split(",") +20 20 | "a,b,c,d".split(None) +21 |-"a,b,c,d".split(",", 1) + 21 |+["a", "b,c,d"] +22 22 | "a,b,c,d".split(None, 1) +23 23 | "a,b,c,d".split(sep=",") +24 24 | "a,b,c,d".split(sep=None) + +SIM905.py:22:1: SIM905 Consider using a list literal instead of `str.split` + | +20 | "a,b,c,d".split(None) +21 | "a,b,c,d".split(",", 1) +22 | "a,b,c,d".split(None, 1) | ^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -16 | "a,b,c,d".split(sep=",") -17 | "a,b,c,d".split(sep=None) +23 | "a,b,c,d".split(sep=",") +24 | "a,b,c,d".split(sep=None) | = help: Replace with list literal -SIM905.py:16:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:23:1: SIM905 [*] Consider using a list literal instead of `str.split` | -14 | "a,b,c,d".split(",", 1) -15 | "a,b,c,d".split(None, 1) -16 | "a,b,c,d".split(sep=",") +21 | "a,b,c,d".split(",", 1) +22 | "a,b,c,d".split(None, 1) +23 | "a,b,c,d".split(sep=",") | ^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -17 | "a,b,c,d".split(sep=None) -18 | "a,b,c,d".split(sep=",", maxsplit=1) +24 | "a,b,c,d".split(sep=None) +25 | "a,b,c,d".split(sep=",", maxsplit=1) | = help: Replace with list literal ℹ Safe fix -13 13 | "a,b,c,d".split(None) -14 14 | "a,b,c,d".split(",", 1) -15 15 | "a,b,c,d".split(None, 1) -16 |-"a,b,c,d".split(sep=",") - 16 |+["a", "b", "c", "d"] -17 17 | "a,b,c,d".split(sep=None) -18 18 | "a,b,c,d".split(sep=",", maxsplit=1) -19 19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 20 | "a,b,c,d".split(None) +21 21 | "a,b,c,d".split(",", 1) +22 22 | "a,b,c,d".split(None, 1) +23 |-"a,b,c,d".split(sep=",") + 23 |+["a", "b", "c", "d"] +24 24 | "a,b,c,d".split(sep=None) +25 25 | "a,b,c,d".split(sep=",", maxsplit=1) +26 26 | "a,b,c,d".split(sep=None, maxsplit=1) -SIM905.py:17:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:24:1: SIM905 [*] Consider using a list literal instead of `str.split` | -15 | "a,b,c,d".split(None, 1) -16 | "a,b,c,d".split(sep=",") -17 | "a,b,c,d".split(sep=None) +22 | "a,b,c,d".split(None, 1) +23 | "a,b,c,d".split(sep=",") +24 | "a,b,c,d".split(sep=None) | ^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -18 | "a,b,c,d".split(sep=",", maxsplit=1) -19 | "a,b,c,d".split(sep=None, maxsplit=1) +25 | "a,b,c,d".split(sep=",", maxsplit=1) +26 | "a,b,c,d".split(sep=None, maxsplit=1) | = help: Replace with list literal ℹ Safe fix -14 14 | "a,b,c,d".split(",", 1) -15 15 | "a,b,c,d".split(None, 1) -16 16 | "a,b,c,d".split(sep=",") -17 |-"a,b,c,d".split(sep=None) - 17 |+["a,b,c,d"] -18 18 | "a,b,c,d".split(sep=",", maxsplit=1) -19 19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 20 | "a,b,c,d".split(maxsplit=1, sep=",") +21 21 | "a,b,c,d".split(",", 1) +22 22 | "a,b,c,d".split(None, 1) +23 23 | "a,b,c,d".split(sep=",") +24 |-"a,b,c,d".split(sep=None) + 24 |+["a,b,c,d"] +25 25 | "a,b,c,d".split(sep=",", maxsplit=1) +26 26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 27 | "a,b,c,d".split(maxsplit=1, sep=",") -SIM905.py:18:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:25:1: SIM905 [*] Consider using a list literal instead of `str.split` | -16 | "a,b,c,d".split(sep=",") -17 | "a,b,c,d".split(sep=None) -18 | "a,b,c,d".split(sep=",", maxsplit=1) +23 | "a,b,c,d".split(sep=",") +24 | "a,b,c,d".split(sep=None) +25 | "a,b,c,d".split(sep=",", maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 | "a,b,c,d".split(maxsplit=1, sep=",") +26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 | "a,b,c,d".split(maxsplit=1, sep=",") | = help: Replace with list literal ℹ Safe fix -15 15 | "a,b,c,d".split(None, 1) -16 16 | "a,b,c,d".split(sep=",") -17 17 | "a,b,c,d".split(sep=None) -18 |-"a,b,c,d".split(sep=",", maxsplit=1) - 18 |+["a", "b,c,d"] -19 19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 20 | "a,b,c,d".split(maxsplit=1, sep=",") -21 21 | "a,b,c,d".split(maxsplit=1, sep=None) +22 22 | "a,b,c,d".split(None, 1) +23 23 | "a,b,c,d".split(sep=",") +24 24 | "a,b,c,d".split(sep=None) +25 |-"a,b,c,d".split(sep=",", maxsplit=1) + 25 |+["a", "b,c,d"] +26 26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 27 | "a,b,c,d".split(maxsplit=1, sep=",") +28 28 | "a,b,c,d".split(maxsplit=1, sep=None) -SIM905.py:19:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:26:1: SIM905 Consider using a list literal instead of `str.split` | -17 | "a,b,c,d".split(sep=None) -18 | "a,b,c,d".split(sep=",", maxsplit=1) -19 | "a,b,c,d".split(sep=None, maxsplit=1) +24 | "a,b,c,d".split(sep=None) +25 | "a,b,c,d".split(sep=",", maxsplit=1) +26 | "a,b,c,d".split(sep=None, maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -20 | "a,b,c,d".split(maxsplit=1, sep=",") -21 | "a,b,c,d".split(maxsplit=1, sep=None) +27 | "a,b,c,d".split(maxsplit=1, sep=",") +28 | "a,b,c,d".split(maxsplit=1, sep=None) | = help: Replace with list literal -SIM905.py:20:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:27:1: SIM905 [*] Consider using a list literal instead of `str.split` | -18 | "a,b,c,d".split(sep=",", maxsplit=1) -19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 | "a,b,c,d".split(maxsplit=1, sep=",") +25 | "a,b,c,d".split(sep=",", maxsplit=1) +26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 | "a,b,c,d".split(maxsplit=1, sep=",") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -21 | "a,b,c,d".split(maxsplit=1, sep=None) -22 | "a,b,c,d".split(",", maxsplit=1) +28 | "a,b,c,d".split(maxsplit=1, sep=None) +29 | "a,b,c,d".split(",", maxsplit=1) | = help: Replace with list literal ℹ Safe fix -17 17 | "a,b,c,d".split(sep=None) -18 18 | "a,b,c,d".split(sep=",", maxsplit=1) -19 19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 |-"a,b,c,d".split(maxsplit=1, sep=",") - 20 |+["a", "b,c,d"] -21 21 | "a,b,c,d".split(maxsplit=1, sep=None) -22 22 | "a,b,c,d".split(",", maxsplit=1) -23 23 | "a,b,c,d".split(None, maxsplit=1) +24 24 | "a,b,c,d".split(sep=None) +25 25 | "a,b,c,d".split(sep=",", maxsplit=1) +26 26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 |-"a,b,c,d".split(maxsplit=1, sep=",") + 27 |+["a", "b,c,d"] +28 28 | "a,b,c,d".split(maxsplit=1, sep=None) +29 29 | "a,b,c,d".split(",", maxsplit=1) +30 30 | "a,b,c,d".split(None, maxsplit=1) -SIM905.py:21:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:28:1: SIM905 Consider using a list literal instead of `str.split` | -19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 | "a,b,c,d".split(maxsplit=1, sep=",") -21 | "a,b,c,d".split(maxsplit=1, sep=None) +26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 | "a,b,c,d".split(maxsplit=1, sep=",") +28 | "a,b,c,d".split(maxsplit=1, sep=None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -22 | "a,b,c,d".split(",", maxsplit=1) -23 | "a,b,c,d".split(None, maxsplit=1) +29 | "a,b,c,d".split(",", maxsplit=1) +30 | "a,b,c,d".split(None, maxsplit=1) | = help: Replace with list literal -SIM905.py:22:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:29:1: SIM905 [*] Consider using a list literal instead of `str.split` | -20 | "a,b,c,d".split(maxsplit=1, sep=",") -21 | "a,b,c,d".split(maxsplit=1, sep=None) -22 | "a,b,c,d".split(",", maxsplit=1) +27 | "a,b,c,d".split(maxsplit=1, sep=",") +28 | "a,b,c,d".split(maxsplit=1, sep=None) +29 | "a,b,c,d".split(",", maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -23 | "a,b,c,d".split(None, maxsplit=1) -24 | "a,b,c,d".split(maxsplit=1) +30 | "a,b,c,d".split(None, maxsplit=1) +31 | "a,b,c,d".split(maxsplit=1) | = help: Replace with list literal ℹ Safe fix -19 19 | "a,b,c,d".split(sep=None, maxsplit=1) -20 20 | "a,b,c,d".split(maxsplit=1, sep=",") -21 21 | "a,b,c,d".split(maxsplit=1, sep=None) -22 |-"a,b,c,d".split(",", maxsplit=1) - 22 |+["a", "b,c,d"] -23 23 | "a,b,c,d".split(None, maxsplit=1) -24 24 | "a,b,c,d".split(maxsplit=1) -25 25 | "a,b,c,d".split(maxsplit=1.0) +26 26 | "a,b,c,d".split(sep=None, maxsplit=1) +27 27 | "a,b,c,d".split(maxsplit=1, sep=",") +28 28 | "a,b,c,d".split(maxsplit=1, sep=None) +29 |-"a,b,c,d".split(",", maxsplit=1) + 29 |+["a", "b,c,d"] +30 30 | "a,b,c,d".split(None, maxsplit=1) +31 31 | "a,b,c,d".split(maxsplit=1) +32 32 | "a,b,c,d".split(maxsplit=1.0) -SIM905.py:23:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:30:1: SIM905 Consider using a list literal instead of `str.split` | -21 | "a,b,c,d".split(maxsplit=1, sep=None) -22 | "a,b,c,d".split(",", maxsplit=1) -23 | "a,b,c,d".split(None, maxsplit=1) +28 | "a,b,c,d".split(maxsplit=1, sep=None) +29 | "a,b,c,d".split(",", maxsplit=1) +30 | "a,b,c,d".split(None, maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -24 | "a,b,c,d".split(maxsplit=1) -25 | "a,b,c,d".split(maxsplit=1.0) +31 | "a,b,c,d".split(maxsplit=1) +32 | "a,b,c,d".split(maxsplit=1.0) | = help: Replace with list literal -SIM905.py:24:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:31:1: SIM905 Consider using a list literal instead of `str.split` | -22 | "a,b,c,d".split(",", maxsplit=1) -23 | "a,b,c,d".split(None, maxsplit=1) -24 | "a,b,c,d".split(maxsplit=1) +29 | "a,b,c,d".split(",", maxsplit=1) +30 | "a,b,c,d".split(None, maxsplit=1) +31 | "a,b,c,d".split(maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -25 | "a,b,c,d".split(maxsplit=1.0) -26 | "a,b,c,d".split(maxsplit=1) +32 | "a,b,c,d".split(maxsplit=1.0) +33 | "a,b,c,d".split(maxsplit=1) | = help: Replace with list literal -SIM905.py:26:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:33:1: SIM905 Consider using a list literal instead of `str.split` | -24 | "a,b,c,d".split(maxsplit=1) -25 | "a,b,c,d".split(maxsplit=1.0) -26 | "a,b,c,d".split(maxsplit=1) +31 | "a,b,c,d".split(maxsplit=1) +32 | "a,b,c,d".split(maxsplit=1.0) +33 | "a,b,c,d".split(maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -27 | "a,b,c,d".split(maxsplit=0) -28 | "VERB AUX PRON ADP DET".split(" ") +34 | "a,b,c,d".split(maxsplit=0) +35 | "VERB AUX PRON ADP DET".split(" ") | = help: Replace with list literal -SIM905.py:27:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:34:1: SIM905 [*] Consider using a list literal instead of `str.split` | -25 | "a,b,c,d".split(maxsplit=1.0) -26 | "a,b,c,d".split(maxsplit=1) -27 | "a,b,c,d".split(maxsplit=0) +32 | "a,b,c,d".split(maxsplit=1.0) +33 | "a,b,c,d".split(maxsplit=1) +34 | "a,b,c,d".split(maxsplit=0) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -28 | "VERB AUX PRON ADP DET".split(" ") -29 | ' 1 2 3 '.split() +35 | "VERB AUX PRON ADP DET".split(" ") +36 | ' 1 2 3 '.split() | = help: Replace with list literal ℹ Safe fix -24 24 | "a,b,c,d".split(maxsplit=1) -25 25 | "a,b,c,d".split(maxsplit=1.0) -26 26 | "a,b,c,d".split(maxsplit=1) -27 |-"a,b,c,d".split(maxsplit=0) - 27 |+["a,b,c,d"] -28 28 | "VERB AUX PRON ADP DET".split(" ") -29 29 | ' 1 2 3 '.split() -30 30 | '1<>2<>3<4'.split('<>') +31 31 | "a,b,c,d".split(maxsplit=1) +32 32 | "a,b,c,d".split(maxsplit=1.0) +33 33 | "a,b,c,d".split(maxsplit=1) +34 |-"a,b,c,d".split(maxsplit=0) + 34 |+["a,b,c,d"] +35 35 | "VERB AUX PRON ADP DET".split(" ") +36 36 | ' 1 2 3 '.split() +37 37 | '1<>2<>3<4'.split('<>') -SIM905.py:28:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:35:1: SIM905 [*] Consider using a list literal instead of `str.split` | -26 | "a,b,c,d".split(maxsplit=1) -27 | "a,b,c,d".split(maxsplit=0) -28 | "VERB AUX PRON ADP DET".split(" ") +33 | "a,b,c,d".split(maxsplit=1) +34 | "a,b,c,d".split(maxsplit=0) +35 | "VERB AUX PRON ADP DET".split(" ") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -29 | ' 1 2 3 '.split() -30 | '1<>2<>3<4'.split('<>') +36 | ' 1 2 3 '.split() +37 | '1<>2<>3<4'.split('<>') | = help: Replace with list literal ℹ Safe fix -25 25 | "a,b,c,d".split(maxsplit=1.0) -26 26 | "a,b,c,d".split(maxsplit=1) -27 27 | "a,b,c,d".split(maxsplit=0) -28 |-"VERB AUX PRON ADP DET".split(" ") - 28 |+["VERB", "AUX", "PRON", "ADP", "DET"] -29 29 | ' 1 2 3 '.split() -30 30 | '1<>2<>3<4'.split('<>') -31 31 | +32 32 | "a,b,c,d".split(maxsplit=1.0) +33 33 | "a,b,c,d".split(maxsplit=1) +34 34 | "a,b,c,d".split(maxsplit=0) +35 |-"VERB AUX PRON ADP DET".split(" ") + 35 |+["VERB", "AUX", "PRON", "ADP", "DET"] +36 36 | ' 1 2 3 '.split() +37 37 | '1<>2<>3<4'.split('<>') +38 38 | -SIM905.py:29:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:36:1: SIM905 [*] Consider using a list literal instead of `str.split` | -27 | "a,b,c,d".split(maxsplit=0) -28 | "VERB AUX PRON ADP DET".split(" ") -29 | ' 1 2 3 '.split() +34 | "a,b,c,d".split(maxsplit=0) +35 | "VERB AUX PRON ADP DET".split(" ") +36 | ' 1 2 3 '.split() | ^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -30 | '1<>2<>3<4'.split('<>') +37 | '1<>2<>3<4'.split('<>') | = help: Replace with list literal ℹ Safe fix -26 26 | "a,b,c,d".split(maxsplit=1) -27 27 | "a,b,c,d".split(maxsplit=0) -28 28 | "VERB AUX PRON ADP DET".split(" ") -29 |-' 1 2 3 '.split() - 29 |+['1', '2', '3'] -30 30 | '1<>2<>3<4'.split('<>') -31 31 | -32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +33 33 | "a,b,c,d".split(maxsplit=1) +34 34 | "a,b,c,d".split(maxsplit=0) +35 35 | "VERB AUX PRON ADP DET".split(" ") +36 |-' 1 2 3 '.split() + 36 |+['1', '2', '3'] +37 37 | '1<>2<>3<4'.split('<>') +38 38 | +39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -SIM905.py:30:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:37:1: SIM905 [*] Consider using a list literal instead of `str.split` | -28 | "VERB AUX PRON ADP DET".split(" ") -29 | ' 1 2 3 '.split() -30 | '1<>2<>3<4'.split('<>') +35 | "VERB AUX PRON ADP DET".split(" ") +36 | ' 1 2 3 '.split() +37 | '1<>2<>3<4'.split('<>') | ^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -31 | -32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +38 | +39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] | = help: Replace with list literal ℹ Safe fix -27 27 | "a,b,c,d".split(maxsplit=0) -28 28 | "VERB AUX PRON ADP DET".split(" ") -29 29 | ' 1 2 3 '.split() -30 |-'1<>2<>3<4'.split('<>') - 30 |+['1', '2', '3<4'] -31 31 | -32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -33 33 | "".split() # [] +34 34 | "a,b,c,d".split(maxsplit=0) +35 35 | "VERB AUX PRON ADP DET".split(" ") +36 36 | ' 1 2 3 '.split() +37 |-'1<>2<>3<4'.split('<>') + 37 |+['1', '2', '3<4'] +38 38 | +39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +40 40 | "".split() # [] -SIM905.py:32:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:39:1: SIM905 [*] Consider using a list literal instead of `str.split` | -30 | '1<>2<>3<4'.split('<>') -31 | -32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +37 | '1<>2<>3<4'.split('<>') +38 | +39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -33 | "".split() # [] -34 | """ +40 | "".split() # [] +41 | """ | = help: Replace with list literal ℹ Safe fix -29 29 | ' 1 2 3 '.split() -30 30 | '1<>2<>3<4'.split('<>') -31 31 | -32 |-" a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] - 32 |+[" a", "a a", "a a "] # [" a", "a a", "a a "] -33 33 | "".split() # [] -34 34 | """ -35 35 | """.split() # [] +36 36 | ' 1 2 3 '.split() +37 37 | '1<>2<>3<4'.split('<>') +38 38 | +39 |-" a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] + 39 |+[" a", "a a", "a a "] # [" a", "a a", "a a "] +40 40 | "".split() # [] +41 41 | """ +42 42 | """.split() # [] -SIM905.py:33:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:40:1: SIM905 [*] Consider using a list literal instead of `str.split` | -32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -33 | "".split() # [] +39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +40 | "".split() # [] | ^^^^^^^^^^ SIM905 -34 | """ -35 | """.split() # [] +41 | """ +42 | """.split() # [] | = help: Replace with list literal ℹ Safe fix -30 30 | '1<>2<>3<4'.split('<>') -31 31 | -32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -33 |-"".split() # [] - 33 |+[] # [] -34 34 | """ -35 35 | """.split() # [] -36 36 | " ".split() # [] +37 37 | '1<>2<>3<4'.split('<>') +38 38 | +39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +40 |-"".split() # [] + 40 |+[] # [] +41 41 | """ +42 42 | """.split() # [] +43 43 | " ".split() # [] -SIM905.py:34:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:41:1: SIM905 [*] Consider using a list literal instead of `str.split` | -32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -33 | "".split() # [] -34 | / """ -35 | | """.split() # [] +39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +40 | "".split() # [] +41 | / """ +42 | | """.split() # [] | |___________^ SIM905 -36 | " ".split() # [] -37 | "/abc/".split() # ["/abc/"] +43 | " ".split() # [] +44 | "/abc/".split() # ["/abc/"] | = help: Replace with list literal ℹ Safe fix -31 31 | -32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -33 33 | "".split() # [] -34 |-""" -35 |-""".split() # [] - 34 |+[] # [] -36 35 | " ".split() # [] -37 36 | "/abc/".split() # ["/abc/"] -38 37 | ("a,b,c" +38 38 | +39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +40 40 | "".split() # [] +41 |-""" +42 |-""".split() # [] + 41 |+[] # [] +43 42 | " ".split() # [] +44 43 | "/abc/".split() # ["/abc/"] +45 44 | ("a,b,c" -SIM905.py:36:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:43:1: SIM905 [*] Consider using a list literal instead of `str.split` | -34 | """ -35 | """.split() # [] -36 | " ".split() # [] +41 | """ +42 | """.split() # [] +43 | " ".split() # [] | ^^^^^^^^^^^^^^^^^ SIM905 -37 | "/abc/".split() # ["/abc/"] -38 | ("a,b,c" +44 | "/abc/".split() # ["/abc/"] +45 | ("a,b,c" | = help: Replace with list literal ℹ Safe fix -33 33 | "".split() # [] -34 34 | """ -35 35 | """.split() # [] -36 |-" ".split() # [] - 36 |+[] # [] -37 37 | "/abc/".split() # ["/abc/"] -38 38 | ("a,b,c" -39 39 | # comment +40 40 | "".split() # [] +41 41 | """ +42 42 | """.split() # [] +43 |-" ".split() # [] + 43 |+[] # [] +44 44 | "/abc/".split() # ["/abc/"] +45 45 | ("a,b,c" +46 46 | # comment -SIM905.py:37:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:44:1: SIM905 [*] Consider using a list literal instead of `str.split` | -35 | """.split() # [] -36 | " ".split() # [] -37 | "/abc/".split() # ["/abc/"] +42 | """.split() # [] +43 | " ".split() # [] +44 | "/abc/".split() # ["/abc/"] | ^^^^^^^^^^^^^^^ SIM905 -38 | ("a,b,c" -39 | # comment +45 | ("a,b,c" +46 | # comment | = help: Replace with list literal ℹ Safe fix -34 34 | """ -35 35 | """.split() # [] -36 36 | " ".split() # [] -37 |-"/abc/".split() # ["/abc/"] - 37 |+["/abc/"] # ["/abc/"] -38 38 | ("a,b,c" -39 39 | # comment -40 40 | .split() +41 41 | """ +42 42 | """.split() # [] +43 43 | " ".split() # [] +44 |-"/abc/".split() # ["/abc/"] + 44 |+["/abc/"] # ["/abc/"] +45 45 | ("a,b,c" +46 46 | # comment +47 47 | .split() -SIM905.py:38:2: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:45:2: SIM905 [*] Consider using a list literal instead of `str.split` | -36 | " ".split() # [] -37 | "/abc/".split() # ["/abc/"] -38 | ("a,b,c" +43 | " ".split() # [] +44 | "/abc/".split() # ["/abc/"] +45 | ("a,b,c" | __^ -39 | | # comment -40 | | .split() +46 | | # comment +47 | | .split() | |________^ SIM905 -41 | ) # ["a,b,c"] -42 | ("a,b,c" +48 | ) # ["a,b,c"] +49 | ("a,b,c" | = help: Replace with list literal ℹ Unsafe fix -35 35 | """.split() # [] -36 36 | " ".split() # [] -37 37 | "/abc/".split() # ["/abc/"] -38 |-("a,b,c" -39 |-# comment -40 |-.split() - 38 |+(["a,b,c"] -41 39 | ) # ["a,b,c"] -42 40 | ("a,b,c" -43 41 | # comment1 - -SIM905.py:42:2: SIM905 [*] Consider using a list literal instead of `str.split` - | -40 | .split() -41 | ) # ["a,b,c"] -42 | ("a,b,c" +42 42 | """.split() # [] +43 43 | " ".split() # [] +44 44 | "/abc/".split() # ["/abc/"] +45 |-("a,b,c" +46 |-# comment +47 |-.split() + 45 |+(["a,b,c"] +48 46 | ) # ["a,b,c"] +49 47 | ("a,b,c" +50 48 | # comment1 + +SIM905.py:49:2: SIM905 [*] Consider using a list literal instead of `str.split` + | +47 | .split() +48 | ) # ["a,b,c"] +49 | ("a,b,c" | __^ -43 | | # comment1 -44 | | .split(",") +50 | | # comment1 +51 | | .split(",") | |___________^ SIM905 -45 | ) # ["a", "b", "c"] -46 | ("a," +52 | ) # ["a", "b", "c"] +53 | ("a," | = help: Replace with list literal ℹ Unsafe fix -39 39 | # comment -40 40 | .split() -41 41 | ) # ["a,b,c"] -42 |-("a,b,c" -43 |-# comment1 -44 |-.split(",") - 42 |+(["a", "b", "c"] -45 43 | ) # ["a", "b", "c"] -46 44 | ("a," -47 45 | # comment - -SIM905.py:46:2: SIM905 [*] Consider using a list literal instead of `str.split` - | -44 | .split(",") -45 | ) # ["a", "b", "c"] -46 | ("a," +46 46 | # comment +47 47 | .split() +48 48 | ) # ["a,b,c"] +49 |-("a,b,c" +50 |-# comment1 +51 |-.split(",") + 49 |+(["a", "b", "c"] +52 50 | ) # ["a", "b", "c"] +53 51 | ("a," +54 52 | # comment + +SIM905.py:53:2: SIM905 [*] Consider using a list literal instead of `str.split` + | +51 | .split(",") +52 | ) # ["a", "b", "c"] +53 | ("a," | __^ -47 | | # comment -48 | | "b," -49 | | "c" -50 | | .split(",") +54 | | # comment +55 | | "b," +56 | | "c" +57 | | .split(",") | |___________^ SIM905 -51 | ) # ["a", "b", "c"] +58 | ) # ["a", "b", "c"] | = help: Replace with list literal ℹ Unsafe fix -43 43 | # comment1 -44 44 | .split(",") -45 45 | ) # ["a", "b", "c"] -46 |-("a," -47 |-# comment -48 |-"b," -49 |-"c" -50 |-.split(",") - 46 |+(["a", "b", "c"] -51 47 | ) # ["a", "b", "c"] -52 48 | -53 49 | "hello "\ - -SIM905.py:53:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -51 | ) # ["a", "b", "c"] -52 | -53 | / "hello "\ -54 | | "world".split() +50 50 | # comment1 +51 51 | .split(",") +52 52 | ) # ["a", "b", "c"] +53 |-("a," +54 |-# comment +55 |-"b," +56 |-"c" +57 |-.split(",") + 53 |+(["a", "b", "c"] +58 54 | ) # ["a", "b", "c"] +59 55 | +60 56 | "hello "\ + +SIM905.py:60:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +58 | ) # ["a", "b", "c"] +59 | +60 | / "hello "\ +61 | | "world".split() | |___________________^ SIM905 -55 | # ["hello", "world"] +62 | # ["hello", "world"] | = help: Replace with list literal ℹ Safe fix -50 50 | .split(",") -51 51 | ) # ["a", "b", "c"] -52 52 | -53 |-"hello "\ -54 |- "world".split() - 53 |+["hello", "world"] -55 54 | # ["hello", "world"] -56 55 | -57 56 | # prefixes and isc +57 57 | .split(",") +58 58 | ) # ["a", "b", "c"] +59 59 | +60 |-"hello "\ +61 |- "world".split() + 60 |+["hello", "world"] +62 61 | # ["hello", "world"] +63 62 | +64 63 | # prefixes and isc -SIM905.py:58:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:65:1: SIM905 [*] Consider using a list literal instead of `str.split` | -57 | # prefixes and isc -58 | u"a b".split() # [u"a", u"b"] +64 | # prefixes and isc +65 | u"a b".split() # [u"a", u"b"] | ^^^^^^^^^^^^^^ SIM905 -59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 | ("a " "b").split() # ["a", "b"] +66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 | ("a " "b").split() # ["a", "b"] | = help: Replace with list literal ℹ Safe fix -55 55 | # ["hello", "world"] -56 56 | -57 57 | # prefixes and isc -58 |-u"a b".split() # [u"a", u"b"] - 58 |+[u"a", u"b"] # [u"a", u"b"] -59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 60 | ("a " "b").split() # ["a", "b"] -61 61 | "a " "b".split() # ["a", "b"] +62 62 | # ["hello", "world"] +63 63 | +64 64 | # prefixes and isc +65 |-u"a b".split() # [u"a", u"b"] + 65 |+[u"a", u"b"] # [u"a", u"b"] +66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 67 | ("a " "b").split() # ["a", "b"] +68 68 | "a " "b".split() # ["a", "b"] -SIM905.py:59:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:66:1: SIM905 [*] Consider using a list literal instead of `str.split` | -57 | # prefixes and isc -58 | u"a b".split() # [u"a", u"b"] -59 | r"a \n b".split() # [r"a", r"\n", r"b"] +64 | # prefixes and isc +65 | u"a b".split() # [u"a", u"b"] +66 | r"a \n b".split() # [r"a", r"\n", r"b"] | ^^^^^^^^^^^^^^^^^ SIM905 -60 | ("a " "b").split() # ["a", "b"] -61 | "a " "b".split() # ["a", "b"] +67 | ("a " "b").split() # ["a", "b"] +68 | "a " "b".split() # ["a", "b"] | = help: Replace with list literal ℹ Safe fix -56 56 | -57 57 | # prefixes and isc -58 58 | u"a b".split() # [u"a", u"b"] -59 |-r"a \n b".split() # [r"a", r"\n", r"b"] - 59 |+[r"a", r"\n", r"b"] # [r"a", r"\n", r"b"] -60 60 | ("a " "b").split() # ["a", "b"] -61 61 | "a " "b".split() # ["a", "b"] -62 62 | u"a " "b".split() # [u"a", u"b"] +63 63 | +64 64 | # prefixes and isc +65 65 | u"a b".split() # [u"a", u"b"] +66 |-r"a \n b".split() # [r"a", r"\n", r"b"] + 66 |+[r"a", r"\n", r"b"] # [r"a", r"\n", r"b"] +67 67 | ("a " "b").split() # ["a", "b"] +68 68 | "a " "b".split() # ["a", "b"] +69 69 | u"a " "b".split() # [u"a", u"b"] -SIM905.py:60:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:67:1: SIM905 [*] Consider using a list literal instead of `str.split` | -58 | u"a b".split() # [u"a", u"b"] -59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 | ("a " "b").split() # ["a", "b"] +65 | u"a b".split() # [u"a", u"b"] +66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 | ("a " "b").split() # ["a", "b"] | ^^^^^^^^^^^^^^^^^^ SIM905 -61 | "a " "b".split() # ["a", "b"] -62 | u"a " "b".split() # [u"a", u"b"] +68 | "a " "b".split() # ["a", "b"] +69 | u"a " "b".split() # [u"a", u"b"] | = help: Replace with list literal ℹ Safe fix -57 57 | # prefixes and isc -58 58 | u"a b".split() # [u"a", u"b"] -59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 |-("a " "b").split() # ["a", "b"] - 60 |+["a", "b"] # ["a", "b"] -61 61 | "a " "b".split() # ["a", "b"] -62 62 | u"a " "b".split() # [u"a", u"b"] -63 63 | "a " u"b".split() # ["a", "b"] +64 64 | # prefixes and isc +65 65 | u"a b".split() # [u"a", u"b"] +66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 |-("a " "b").split() # ["a", "b"] + 67 |+["a", "b"] # ["a", "b"] +68 68 | "a " "b".split() # ["a", "b"] +69 69 | u"a " "b".split() # [u"a", u"b"] +70 70 | "a " u"b".split() # ["a", "b"] -SIM905.py:61:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:68:1: SIM905 [*] Consider using a list literal instead of `str.split` | -59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 | ("a " "b").split() # ["a", "b"] -61 | "a " "b".split() # ["a", "b"] +66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 | ("a " "b").split() # ["a", "b"] +68 | "a " "b".split() # ["a", "b"] | ^^^^^^^^^^^^^^^^ SIM905 -62 | u"a " "b".split() # [u"a", u"b"] -63 | "a " u"b".split() # ["a", "b"] +69 | u"a " "b".split() # [u"a", u"b"] +70 | "a " u"b".split() # ["a", "b"] | = help: Replace with list literal ℹ Safe fix -58 58 | u"a b".split() # [u"a", u"b"] -59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 60 | ("a " "b").split() # ["a", "b"] -61 |-"a " "b".split() # ["a", "b"] - 61 |+["a", "b"] # ["a", "b"] -62 62 | u"a " "b".split() # [u"a", u"b"] -63 63 | "a " u"b".split() # ["a", "b"] -64 64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 65 | u"a b".split() # [u"a", u"b"] +66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 67 | ("a " "b").split() # ["a", "b"] +68 |-"a " "b".split() # ["a", "b"] + 68 |+["a", "b"] # ["a", "b"] +69 69 | u"a " "b".split() # [u"a", u"b"] +70 70 | "a " u"b".split() # ["a", "b"] +71 71 | u"a " r"\n".split() # [u"a", u"\\n"] -SIM905.py:62:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:69:1: SIM905 [*] Consider using a list literal instead of `str.split` | -60 | ("a " "b").split() # ["a", "b"] -61 | "a " "b".split() # ["a", "b"] -62 | u"a " "b".split() # [u"a", u"b"] +67 | ("a " "b").split() # ["a", "b"] +68 | "a " "b".split() # ["a", "b"] +69 | u"a " "b".split() # [u"a", u"b"] | ^^^^^^^^^^^^^^^^^ SIM905 -63 | "a " u"b".split() # ["a", "b"] -64 | u"a " r"\n".split() # [u"a", u"\\n"] +70 | "a " u"b".split() # ["a", "b"] +71 | u"a " r"\n".split() # [u"a", u"\\n"] | = help: Replace with list literal ℹ Safe fix -59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] -60 60 | ("a " "b").split() # ["a", "b"] -61 61 | "a " "b".split() # ["a", "b"] -62 |-u"a " "b".split() # [u"a", u"b"] - 62 |+[u"a", u"b"] # [u"a", u"b"] -63 63 | "a " u"b".split() # ["a", "b"] -64 64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 65 | r"\n " u"\n".split() # [r"\n"] +66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] +67 67 | ("a " "b").split() # ["a", "b"] +68 68 | "a " "b".split() # ["a", "b"] +69 |-u"a " "b".split() # [u"a", u"b"] + 69 |+[u"a", u"b"] # [u"a", u"b"] +70 70 | "a " u"b".split() # ["a", "b"] +71 71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 72 | r"\n " u"\n".split() # [r"\n"] -SIM905.py:63:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:70:1: SIM905 [*] Consider using a list literal instead of `str.split` | -61 | "a " "b".split() # ["a", "b"] -62 | u"a " "b".split() # [u"a", u"b"] -63 | "a " u"b".split() # ["a", "b"] +68 | "a " "b".split() # ["a", "b"] +69 | u"a " "b".split() # [u"a", u"b"] +70 | "a " u"b".split() # ["a", "b"] | ^^^^^^^^^^^^^^^^^ SIM905 -64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 | r"\n " u"\n".split() # [r"\n"] +71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 | r"\n " u"\n".split() # [r"\n"] | = help: Replace with list literal ℹ Safe fix -60 60 | ("a " "b").split() # ["a", "b"] -61 61 | "a " "b".split() # ["a", "b"] -62 62 | u"a " "b".split() # [u"a", u"b"] -63 |-"a " u"b".split() # ["a", "b"] - 63 |+["a", "b"] # ["a", "b"] -64 64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 65 | r"\n " u"\n".split() # [r"\n"] -66 66 | r"\n " "\n".split() # [r"\n"] +67 67 | ("a " "b").split() # ["a", "b"] +68 68 | "a " "b".split() # ["a", "b"] +69 69 | u"a " "b".split() # [u"a", u"b"] +70 |-"a " u"b".split() # ["a", "b"] + 70 |+["a", "b"] # ["a", "b"] +71 71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 72 | r"\n " u"\n".split() # [r"\n"] +73 73 | r"\n " "\n".split() # [r"\n"] -SIM905.py:64:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:71:1: SIM905 [*] Consider using a list literal instead of `str.split` | -62 | u"a " "b".split() # [u"a", u"b"] -63 | "a " u"b".split() # ["a", "b"] -64 | u"a " r"\n".split() # [u"a", u"\\n"] +69 | u"a " "b".split() # [u"a", u"b"] +70 | "a " u"b".split() # ["a", "b"] +71 | u"a " r"\n".split() # [u"a", u"\\n"] | ^^^^^^^^^^^^^^^^^^^ SIM905 -65 | r"\n " u"\n".split() # [r"\n"] -66 | r"\n " "\n".split() # [r"\n"] +72 | r"\n " u"\n".split() # [r"\n"] +73 | r"\n " "\n".split() # [r"\n"] | = help: Replace with list literal ℹ Safe fix -61 61 | "a " "b".split() # ["a", "b"] -62 62 | u"a " "b".split() # [u"a", u"b"] -63 63 | "a " u"b".split() # ["a", "b"] -64 |-u"a " r"\n".split() # [u"a", u"\\n"] - 64 |+[u"a", u"\\n"] # [u"a", u"\\n"] -65 65 | r"\n " u"\n".split() # [r"\n"] -66 66 | r"\n " "\n".split() # [r"\n"] -67 67 | "a " r"\n".split() # ["a", "\\n"] +68 68 | "a " "b".split() # ["a", "b"] +69 69 | u"a " "b".split() # [u"a", u"b"] +70 70 | "a " u"b".split() # ["a", "b"] +71 |-u"a " r"\n".split() # [u"a", u"\\n"] + 71 |+[u"a", u"\\n"] # [u"a", u"\\n"] +72 72 | r"\n " u"\n".split() # [r"\n"] +73 73 | r"\n " "\n".split() # [r"\n"] +74 74 | "a " r"\n".split() # ["a", "\\n"] -SIM905.py:65:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:72:1: SIM905 [*] Consider using a list literal instead of `str.split` | -63 | "a " u"b".split() # ["a", "b"] -64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 | r"\n " u"\n".split() # [r"\n"] +70 | "a " u"b".split() # ["a", "b"] +71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 | r"\n " u"\n".split() # [r"\n"] | ^^^^^^^^^^^^^^^^^^^^ SIM905 -66 | r"\n " "\n".split() # [r"\n"] -67 | "a " r"\n".split() # ["a", "\\n"] +73 | r"\n " "\n".split() # [r"\n"] +74 | "a " r"\n".split() # ["a", "\\n"] | = help: Replace with list literal ℹ Safe fix -62 62 | u"a " "b".split() # [u"a", u"b"] -63 63 | "a " u"b".split() # ["a", "b"] -64 64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 |-r"\n " u"\n".split() # [r"\n"] - 65 |+[r"\n"] # [r"\n"] -66 66 | r"\n " "\n".split() # [r"\n"] -67 67 | "a " r"\n".split() # ["a", "\\n"] -68 68 | +69 69 | u"a " "b".split() # [u"a", u"b"] +70 70 | "a " u"b".split() # ["a", "b"] +71 71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 |-r"\n " u"\n".split() # [r"\n"] + 72 |+[r"\n"] # [r"\n"] +73 73 | r"\n " "\n".split() # [r"\n"] +74 74 | "a " r"\n".split() # ["a", "\\n"] +75 75 | -SIM905.py:66:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:73:1: SIM905 [*] Consider using a list literal instead of `str.split` | -64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 | r"\n " u"\n".split() # [r"\n"] -66 | r"\n " "\n".split() # [r"\n"] +71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 | r"\n " u"\n".split() # [r"\n"] +73 | r"\n " "\n".split() # [r"\n"] | ^^^^^^^^^^^^^^^^^^^ SIM905 -67 | "a " r"\n".split() # ["a", "\\n"] +74 | "a " r"\n".split() # ["a", "\\n"] | = help: Replace with list literal ℹ Safe fix -63 63 | "a " u"b".split() # ["a", "b"] -64 64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 65 | r"\n " u"\n".split() # [r"\n"] -66 |-r"\n " "\n".split() # [r"\n"] - 66 |+[r"\n"] # [r"\n"] -67 67 | "a " r"\n".split() # ["a", "\\n"] -68 68 | -69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 70 | "a " u"b".split() # ["a", "b"] +71 71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 72 | r"\n " u"\n".split() # [r"\n"] +73 |-r"\n " "\n".split() # [r"\n"] + 73 |+[r"\n"] # [r"\n"] +74 74 | "a " r"\n".split() # ["a", "\\n"] +75 75 | +76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -SIM905.py:67:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:74:1: SIM905 [*] Consider using a list literal instead of `str.split` | -65 | r"\n " u"\n".split() # [r"\n"] -66 | r"\n " "\n".split() # [r"\n"] -67 | "a " r"\n".split() # ["a", "\\n"] +72 | r"\n " u"\n".split() # [r"\n"] +73 | r"\n " "\n".split() # [r"\n"] +74 | "a " r"\n".split() # ["a", "\\n"] | ^^^^^^^^^^^^^^^^^^ SIM905 -68 | -69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +75 | +76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] | = help: Replace with list literal ℹ Safe fix -64 64 | u"a " r"\n".split() # [u"a", u"\\n"] -65 65 | r"\n " u"\n".split() # [r"\n"] -66 66 | r"\n " "\n".split() # [r"\n"] -67 |-"a " r"\n".split() # ["a", "\\n"] - 67 |+["a", "\\n"] # ["a", "\\n"] -68 68 | -69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 71 | u"a " r"\n".split() # [u"a", u"\\n"] +72 72 | r"\n " u"\n".split() # [r"\n"] +73 73 | r"\n " "\n".split() # [r"\n"] +74 |-"a " r"\n".split() # ["a", "\\n"] + 74 |+["a", "\\n"] # ["a", "\\n"] +75 75 | +76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -SIM905.py:69:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:76:1: SIM905 [*] Consider using a list literal instead of `str.split` | -67 | "a " r"\n".split() # ["a", "\\n"] -68 | -69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +74 | "a " r"\n".split() # ["a", "\\n"] +75 | +76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] | = help: Replace with list literal ℹ Safe fix -66 66 | r"\n " "\n".split() # [r"\n"] -67 67 | "a " r"\n".split() # ["a", "\\n"] -68 68 | -69 |-"a,b,c".split(',', maxsplit=0) # ["a,b,c"] - 69 |+["a,b,c"] # ["a,b,c"] -70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -71 71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -72 72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +73 73 | r"\n " "\n".split() # [r"\n"] +74 74 | "a " r"\n".split() # ["a", "\\n"] +75 75 | +76 |-"a,b,c".split(',', maxsplit=0) # ["a,b,c"] + 76 |+["a,b,c"] # ["a,b,c"] +77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +78 78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +79 79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] -SIM905.py:70:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:77:1: SIM905 [*] Consider using a list literal instead of `str.split` | -69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] | = help: Replace with list literal ℹ Safe fix -67 67 | "a " r"\n".split() # ["a", "\\n"] -68 68 | -69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -70 |-"a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] - 70 |+["a", "b", "c"] # ["a", "b", "c"] -71 71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -72 72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] -73 73 | +74 74 | "a " r"\n".split() # ["a", "\\n"] +75 75 | +76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +77 |-"a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] + 77 |+["a", "b", "c"] # ["a", "b", "c"] +78 78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +79 79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +80 80 | -SIM905.py:71:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:78:1: SIM905 [*] Consider using a list literal instead of `str.split` | -69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] | = help: Replace with list literal ℹ Safe fix -68 68 | -69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -71 |-"a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] - 71 |+["a", "b", "c"] # ["a", "b", "c"] -72 72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] -73 73 | -74 74 | # negatives +75 75 | +76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +78 |-"a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] + 78 |+["a", "b", "c"] # ["a", "b", "c"] +79 79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +80 80 | +81 81 | # negatives -SIM905.py:72:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:79:1: SIM905 [*] Consider using a list literal instead of `str.split` | -70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -73 | -74 | # negatives +80 | +81 | # negatives | = help: Replace with list literal ℹ Safe fix -69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -71 71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -72 |-"a,b,c".split(',', maxsplit=-0) # ["a,b,c"] - 72 |+["a,b,c"] # ["a,b,c"] -73 73 | -74 74 | # negatives -75 75 | +76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +78 78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +79 |-"a,b,c".split(',', maxsplit=-0) # ["a,b,c"] + 79 |+["a,b,c"] # ["a,b,c"] +80 80 | +81 81 | # negatives +82 82 | From 41f5f5eda531fc71562cee94a8daef79d33df7d9 Mon Sep 17 00:00:00 2001 From: Brent Westbrook Date: Mon, 3 Feb 2025 12:41:07 -0500 Subject: [PATCH 28/28] move test case to the bottom --- .../test/fixtures/flake8_simplify/SIM905.py | 16 +- ...ke8_simplify__tests__SIM905_SIM905.py.snap | 1156 ++++++++--------- 2 files changed, 584 insertions(+), 588 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py index e47d1c497004d..7d767d475385b 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM905.py @@ -9,13 +9,6 @@ itemC """.split() -""" -"itemA" -'itemB' -'''itemC''' -"'itemD'" -""".split() - "a,b,c,d".split(",") "a,b,c,d".split(None) "a,b,c,d".split(",", 1) @@ -104,3 +97,12 @@ "hello\nworld".splitlines() "hello\nworld".splitlines(keepends=True) "hello\nworld".splitlines(keepends=False) + + +# another positive demonstrating quote preservation +""" +"itemA" +'itemB' +'''itemC''' +"'itemD'" +""".split() diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap index e9a47afebc721..62db77198bc15 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM905_SIM905.py.snap @@ -11,7 +11,7 @@ SIM905.py:6:1: SIM905 [*] Consider using a list literal instead of `str.split` 10 | | """.split() | |___________^ SIM905 11 | -12 | """ +12 | "a,b,c,d".split(",") | = help: Replace with list literal @@ -26,22 +26,17 @@ SIM905.py:6:1: SIM905 [*] Consider using a list literal instead of `str.split` 10 |-""".split() 6 |+["itemA", "itemB", "itemC"] 11 7 | -12 8 | """ -13 9 | "itemA" +12 8 | "a,b,c,d".split(",") +13 9 | "a,b,c,d".split(None) SIM905.py:12:1: SIM905 [*] Consider using a list literal instead of `str.split` | -10 | """.split() +10 | """.split() 11 | -12 | / """ -13 | | "itemA" -14 | | 'itemB' -15 | | '''itemC''' -16 | | "'itemD'" -17 | | """.split() - | |___________^ SIM905 -18 | -19 | "a,b,c,d".split(",") +12 | "a,b,c,d".split(",") + | ^^^^^^^^^^^^^^^^^^^^ SIM905 +13 | "a,b,c,d".split(None) +14 | "a,b,c,d".split(",", 1) | = help: Replace with list literal @@ -49,828 +44,827 @@ SIM905.py:12:1: SIM905 [*] Consider using a list literal instead of `str.split` 9 9 | itemC 10 10 | """.split() 11 11 | -12 |-""" -13 |-"itemA" -14 |-'itemB' -15 |-'''itemC''' -16 |-"'itemD'" -17 |-""".split() - 12 |+['"itemA"', "'itemB'", "'''itemC'''", "\"'itemD'\""] -18 13 | -19 14 | "a,b,c,d".split(",") -20 15 | "a,b,c,d".split(None) - -SIM905.py:19:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -17 | """.split() -18 | -19 | "a,b,c,d".split(",") - | ^^^^^^^^^^^^^^^^^^^^ SIM905 -20 | "a,b,c,d".split(None) -21 | "a,b,c,d".split(",", 1) - | - = help: Replace with list literal - -ℹ Safe fix -16 16 | "'itemD'" -17 17 | """.split() -18 18 | -19 |-"a,b,c,d".split(",") - 19 |+["a", "b", "c", "d"] -20 20 | "a,b,c,d".split(None) -21 21 | "a,b,c,d".split(",", 1) -22 22 | "a,b,c,d".split(None, 1) +12 |-"a,b,c,d".split(",") + 12 |+["a", "b", "c", "d"] +13 13 | "a,b,c,d".split(None) +14 14 | "a,b,c,d".split(",", 1) +15 15 | "a,b,c,d".split(None, 1) -SIM905.py:20:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:13:1: SIM905 [*] Consider using a list literal instead of `str.split` | -19 | "a,b,c,d".split(",") -20 | "a,b,c,d".split(None) +12 | "a,b,c,d".split(",") +13 | "a,b,c,d".split(None) | ^^^^^^^^^^^^^^^^^^^^^ SIM905 -21 | "a,b,c,d".split(",", 1) -22 | "a,b,c,d".split(None, 1) +14 | "a,b,c,d".split(",", 1) +15 | "a,b,c,d".split(None, 1) | = help: Replace with list literal ℹ Safe fix -17 17 | """.split() -18 18 | -19 19 | "a,b,c,d".split(",") -20 |-"a,b,c,d".split(None) - 20 |+["a,b,c,d"] -21 21 | "a,b,c,d".split(",", 1) -22 22 | "a,b,c,d".split(None, 1) -23 23 | "a,b,c,d".split(sep=",") - -SIM905.py:21:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -19 | "a,b,c,d".split(",") -20 | "a,b,c,d".split(None) -21 | "a,b,c,d".split(",", 1) +10 10 | """.split() +11 11 | +12 12 | "a,b,c,d".split(",") +13 |-"a,b,c,d".split(None) + 13 |+["a,b,c,d"] +14 14 | "a,b,c,d".split(",", 1) +15 15 | "a,b,c,d".split(None, 1) +16 16 | "a,b,c,d".split(sep=",") + +SIM905.py:14:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +12 | "a,b,c,d".split(",") +13 | "a,b,c,d".split(None) +14 | "a,b,c,d".split(",", 1) | ^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -22 | "a,b,c,d".split(None, 1) -23 | "a,b,c,d".split(sep=",") +15 | "a,b,c,d".split(None, 1) +16 | "a,b,c,d".split(sep=",") | = help: Replace with list literal ℹ Safe fix -18 18 | -19 19 | "a,b,c,d".split(",") -20 20 | "a,b,c,d".split(None) -21 |-"a,b,c,d".split(",", 1) - 21 |+["a", "b,c,d"] -22 22 | "a,b,c,d".split(None, 1) -23 23 | "a,b,c,d".split(sep=",") -24 24 | "a,b,c,d".split(sep=None) - -SIM905.py:22:1: SIM905 Consider using a list literal instead of `str.split` - | -20 | "a,b,c,d".split(None) -21 | "a,b,c,d".split(",", 1) -22 | "a,b,c,d".split(None, 1) +11 11 | +12 12 | "a,b,c,d".split(",") +13 13 | "a,b,c,d".split(None) +14 |-"a,b,c,d".split(",", 1) + 14 |+["a", "b,c,d"] +15 15 | "a,b,c,d".split(None, 1) +16 16 | "a,b,c,d".split(sep=",") +17 17 | "a,b,c,d".split(sep=None) + +SIM905.py:15:1: SIM905 Consider using a list literal instead of `str.split` + | +13 | "a,b,c,d".split(None) +14 | "a,b,c,d".split(",", 1) +15 | "a,b,c,d".split(None, 1) | ^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -23 | "a,b,c,d".split(sep=",") -24 | "a,b,c,d".split(sep=None) +16 | "a,b,c,d".split(sep=",") +17 | "a,b,c,d".split(sep=None) | = help: Replace with list literal -SIM905.py:23:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:16:1: SIM905 [*] Consider using a list literal instead of `str.split` | -21 | "a,b,c,d".split(",", 1) -22 | "a,b,c,d".split(None, 1) -23 | "a,b,c,d".split(sep=",") +14 | "a,b,c,d".split(",", 1) +15 | "a,b,c,d".split(None, 1) +16 | "a,b,c,d".split(sep=",") | ^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -24 | "a,b,c,d".split(sep=None) -25 | "a,b,c,d".split(sep=",", maxsplit=1) +17 | "a,b,c,d".split(sep=None) +18 | "a,b,c,d".split(sep=",", maxsplit=1) | = help: Replace with list literal ℹ Safe fix -20 20 | "a,b,c,d".split(None) -21 21 | "a,b,c,d".split(",", 1) -22 22 | "a,b,c,d".split(None, 1) -23 |-"a,b,c,d".split(sep=",") - 23 |+["a", "b", "c", "d"] -24 24 | "a,b,c,d".split(sep=None) -25 25 | "a,b,c,d".split(sep=",", maxsplit=1) -26 26 | "a,b,c,d".split(sep=None, maxsplit=1) +13 13 | "a,b,c,d".split(None) +14 14 | "a,b,c,d".split(",", 1) +15 15 | "a,b,c,d".split(None, 1) +16 |-"a,b,c,d".split(sep=",") + 16 |+["a", "b", "c", "d"] +17 17 | "a,b,c,d".split(sep=None) +18 18 | "a,b,c,d".split(sep=",", maxsplit=1) +19 19 | "a,b,c,d".split(sep=None, maxsplit=1) -SIM905.py:24:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:17:1: SIM905 [*] Consider using a list literal instead of `str.split` | -22 | "a,b,c,d".split(None, 1) -23 | "a,b,c,d".split(sep=",") -24 | "a,b,c,d".split(sep=None) +15 | "a,b,c,d".split(None, 1) +16 | "a,b,c,d".split(sep=",") +17 | "a,b,c,d".split(sep=None) | ^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -25 | "a,b,c,d".split(sep=",", maxsplit=1) -26 | "a,b,c,d".split(sep=None, maxsplit=1) +18 | "a,b,c,d".split(sep=",", maxsplit=1) +19 | "a,b,c,d".split(sep=None, maxsplit=1) | = help: Replace with list literal ℹ Safe fix -21 21 | "a,b,c,d".split(",", 1) -22 22 | "a,b,c,d".split(None, 1) -23 23 | "a,b,c,d".split(sep=",") -24 |-"a,b,c,d".split(sep=None) - 24 |+["a,b,c,d"] -25 25 | "a,b,c,d".split(sep=",", maxsplit=1) -26 26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 27 | "a,b,c,d".split(maxsplit=1, sep=",") +14 14 | "a,b,c,d".split(",", 1) +15 15 | "a,b,c,d".split(None, 1) +16 16 | "a,b,c,d".split(sep=",") +17 |-"a,b,c,d".split(sep=None) + 17 |+["a,b,c,d"] +18 18 | "a,b,c,d".split(sep=",", maxsplit=1) +19 19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 20 | "a,b,c,d".split(maxsplit=1, sep=",") -SIM905.py:25:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:18:1: SIM905 [*] Consider using a list literal instead of `str.split` | -23 | "a,b,c,d".split(sep=",") -24 | "a,b,c,d".split(sep=None) -25 | "a,b,c,d".split(sep=",", maxsplit=1) +16 | "a,b,c,d".split(sep=",") +17 | "a,b,c,d".split(sep=None) +18 | "a,b,c,d".split(sep=",", maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 | "a,b,c,d".split(maxsplit=1, sep=",") +19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 | "a,b,c,d".split(maxsplit=1, sep=",") | = help: Replace with list literal ℹ Safe fix -22 22 | "a,b,c,d".split(None, 1) -23 23 | "a,b,c,d".split(sep=",") -24 24 | "a,b,c,d".split(sep=None) -25 |-"a,b,c,d".split(sep=",", maxsplit=1) - 25 |+["a", "b,c,d"] -26 26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 27 | "a,b,c,d".split(maxsplit=1, sep=",") -28 28 | "a,b,c,d".split(maxsplit=1, sep=None) +15 15 | "a,b,c,d".split(None, 1) +16 16 | "a,b,c,d".split(sep=",") +17 17 | "a,b,c,d".split(sep=None) +18 |-"a,b,c,d".split(sep=",", maxsplit=1) + 18 |+["a", "b,c,d"] +19 19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 20 | "a,b,c,d".split(maxsplit=1, sep=",") +21 21 | "a,b,c,d".split(maxsplit=1, sep=None) -SIM905.py:26:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:19:1: SIM905 Consider using a list literal instead of `str.split` | -24 | "a,b,c,d".split(sep=None) -25 | "a,b,c,d".split(sep=",", maxsplit=1) -26 | "a,b,c,d".split(sep=None, maxsplit=1) +17 | "a,b,c,d".split(sep=None) +18 | "a,b,c,d".split(sep=",", maxsplit=1) +19 | "a,b,c,d".split(sep=None, maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -27 | "a,b,c,d".split(maxsplit=1, sep=",") -28 | "a,b,c,d".split(maxsplit=1, sep=None) +20 | "a,b,c,d".split(maxsplit=1, sep=",") +21 | "a,b,c,d".split(maxsplit=1, sep=None) | = help: Replace with list literal -SIM905.py:27:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:20:1: SIM905 [*] Consider using a list literal instead of `str.split` | -25 | "a,b,c,d".split(sep=",", maxsplit=1) -26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 | "a,b,c,d".split(maxsplit=1, sep=",") +18 | "a,b,c,d".split(sep=",", maxsplit=1) +19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 | "a,b,c,d".split(maxsplit=1, sep=",") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -28 | "a,b,c,d".split(maxsplit=1, sep=None) -29 | "a,b,c,d".split(",", maxsplit=1) +21 | "a,b,c,d".split(maxsplit=1, sep=None) +22 | "a,b,c,d".split(",", maxsplit=1) | = help: Replace with list literal ℹ Safe fix -24 24 | "a,b,c,d".split(sep=None) -25 25 | "a,b,c,d".split(sep=",", maxsplit=1) -26 26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 |-"a,b,c,d".split(maxsplit=1, sep=",") - 27 |+["a", "b,c,d"] -28 28 | "a,b,c,d".split(maxsplit=1, sep=None) -29 29 | "a,b,c,d".split(",", maxsplit=1) -30 30 | "a,b,c,d".split(None, maxsplit=1) +17 17 | "a,b,c,d".split(sep=None) +18 18 | "a,b,c,d".split(sep=",", maxsplit=1) +19 19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 |-"a,b,c,d".split(maxsplit=1, sep=",") + 20 |+["a", "b,c,d"] +21 21 | "a,b,c,d".split(maxsplit=1, sep=None) +22 22 | "a,b,c,d".split(",", maxsplit=1) +23 23 | "a,b,c,d".split(None, maxsplit=1) -SIM905.py:28:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:21:1: SIM905 Consider using a list literal instead of `str.split` | -26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 | "a,b,c,d".split(maxsplit=1, sep=",") -28 | "a,b,c,d".split(maxsplit=1, sep=None) +19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 | "a,b,c,d".split(maxsplit=1, sep=",") +21 | "a,b,c,d".split(maxsplit=1, sep=None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -29 | "a,b,c,d".split(",", maxsplit=1) -30 | "a,b,c,d".split(None, maxsplit=1) +22 | "a,b,c,d".split(",", maxsplit=1) +23 | "a,b,c,d".split(None, maxsplit=1) | = help: Replace with list literal -SIM905.py:29:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:22:1: SIM905 [*] Consider using a list literal instead of `str.split` | -27 | "a,b,c,d".split(maxsplit=1, sep=",") -28 | "a,b,c,d".split(maxsplit=1, sep=None) -29 | "a,b,c,d".split(",", maxsplit=1) +20 | "a,b,c,d".split(maxsplit=1, sep=",") +21 | "a,b,c,d".split(maxsplit=1, sep=None) +22 | "a,b,c,d".split(",", maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -30 | "a,b,c,d".split(None, maxsplit=1) -31 | "a,b,c,d".split(maxsplit=1) +23 | "a,b,c,d".split(None, maxsplit=1) +24 | "a,b,c,d".split(maxsplit=1) | = help: Replace with list literal ℹ Safe fix -26 26 | "a,b,c,d".split(sep=None, maxsplit=1) -27 27 | "a,b,c,d".split(maxsplit=1, sep=",") -28 28 | "a,b,c,d".split(maxsplit=1, sep=None) -29 |-"a,b,c,d".split(",", maxsplit=1) - 29 |+["a", "b,c,d"] -30 30 | "a,b,c,d".split(None, maxsplit=1) -31 31 | "a,b,c,d".split(maxsplit=1) -32 32 | "a,b,c,d".split(maxsplit=1.0) +19 19 | "a,b,c,d".split(sep=None, maxsplit=1) +20 20 | "a,b,c,d".split(maxsplit=1, sep=",") +21 21 | "a,b,c,d".split(maxsplit=1, sep=None) +22 |-"a,b,c,d".split(",", maxsplit=1) + 22 |+["a", "b,c,d"] +23 23 | "a,b,c,d".split(None, maxsplit=1) +24 24 | "a,b,c,d".split(maxsplit=1) +25 25 | "a,b,c,d".split(maxsplit=1.0) -SIM905.py:30:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:23:1: SIM905 Consider using a list literal instead of `str.split` | -28 | "a,b,c,d".split(maxsplit=1, sep=None) -29 | "a,b,c,d".split(",", maxsplit=1) -30 | "a,b,c,d".split(None, maxsplit=1) +21 | "a,b,c,d".split(maxsplit=1, sep=None) +22 | "a,b,c,d".split(",", maxsplit=1) +23 | "a,b,c,d".split(None, maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -31 | "a,b,c,d".split(maxsplit=1) -32 | "a,b,c,d".split(maxsplit=1.0) +24 | "a,b,c,d".split(maxsplit=1) +25 | "a,b,c,d".split(maxsplit=1.0) | = help: Replace with list literal -SIM905.py:31:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:24:1: SIM905 Consider using a list literal instead of `str.split` | -29 | "a,b,c,d".split(",", maxsplit=1) -30 | "a,b,c,d".split(None, maxsplit=1) -31 | "a,b,c,d".split(maxsplit=1) +22 | "a,b,c,d".split(",", maxsplit=1) +23 | "a,b,c,d".split(None, maxsplit=1) +24 | "a,b,c,d".split(maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -32 | "a,b,c,d".split(maxsplit=1.0) -33 | "a,b,c,d".split(maxsplit=1) +25 | "a,b,c,d".split(maxsplit=1.0) +26 | "a,b,c,d".split(maxsplit=1) | = help: Replace with list literal -SIM905.py:33:1: SIM905 Consider using a list literal instead of `str.split` +SIM905.py:26:1: SIM905 Consider using a list literal instead of `str.split` | -31 | "a,b,c,d".split(maxsplit=1) -32 | "a,b,c,d".split(maxsplit=1.0) -33 | "a,b,c,d".split(maxsplit=1) +24 | "a,b,c,d".split(maxsplit=1) +25 | "a,b,c,d".split(maxsplit=1.0) +26 | "a,b,c,d".split(maxsplit=1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -34 | "a,b,c,d".split(maxsplit=0) -35 | "VERB AUX PRON ADP DET".split(" ") +27 | "a,b,c,d".split(maxsplit=0) +28 | "VERB AUX PRON ADP DET".split(" ") | = help: Replace with list literal -SIM905.py:34:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:27:1: SIM905 [*] Consider using a list literal instead of `str.split` | -32 | "a,b,c,d".split(maxsplit=1.0) -33 | "a,b,c,d".split(maxsplit=1) -34 | "a,b,c,d".split(maxsplit=0) +25 | "a,b,c,d".split(maxsplit=1.0) +26 | "a,b,c,d".split(maxsplit=1) +27 | "a,b,c,d".split(maxsplit=0) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -35 | "VERB AUX PRON ADP DET".split(" ") -36 | ' 1 2 3 '.split() +28 | "VERB AUX PRON ADP DET".split(" ") +29 | ' 1 2 3 '.split() | = help: Replace with list literal ℹ Safe fix -31 31 | "a,b,c,d".split(maxsplit=1) -32 32 | "a,b,c,d".split(maxsplit=1.0) -33 33 | "a,b,c,d".split(maxsplit=1) -34 |-"a,b,c,d".split(maxsplit=0) - 34 |+["a,b,c,d"] -35 35 | "VERB AUX PRON ADP DET".split(" ") -36 36 | ' 1 2 3 '.split() -37 37 | '1<>2<>3<4'.split('<>') +24 24 | "a,b,c,d".split(maxsplit=1) +25 25 | "a,b,c,d".split(maxsplit=1.0) +26 26 | "a,b,c,d".split(maxsplit=1) +27 |-"a,b,c,d".split(maxsplit=0) + 27 |+["a,b,c,d"] +28 28 | "VERB AUX PRON ADP DET".split(" ") +29 29 | ' 1 2 3 '.split() +30 30 | '1<>2<>3<4'.split('<>') -SIM905.py:35:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:28:1: SIM905 [*] Consider using a list literal instead of `str.split` | -33 | "a,b,c,d".split(maxsplit=1) -34 | "a,b,c,d".split(maxsplit=0) -35 | "VERB AUX PRON ADP DET".split(" ") +26 | "a,b,c,d".split(maxsplit=1) +27 | "a,b,c,d".split(maxsplit=0) +28 | "VERB AUX PRON ADP DET".split(" ") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -36 | ' 1 2 3 '.split() -37 | '1<>2<>3<4'.split('<>') +29 | ' 1 2 3 '.split() +30 | '1<>2<>3<4'.split('<>') | = help: Replace with list literal ℹ Safe fix -32 32 | "a,b,c,d".split(maxsplit=1.0) -33 33 | "a,b,c,d".split(maxsplit=1) -34 34 | "a,b,c,d".split(maxsplit=0) -35 |-"VERB AUX PRON ADP DET".split(" ") - 35 |+["VERB", "AUX", "PRON", "ADP", "DET"] -36 36 | ' 1 2 3 '.split() -37 37 | '1<>2<>3<4'.split('<>') -38 38 | +25 25 | "a,b,c,d".split(maxsplit=1.0) +26 26 | "a,b,c,d".split(maxsplit=1) +27 27 | "a,b,c,d".split(maxsplit=0) +28 |-"VERB AUX PRON ADP DET".split(" ") + 28 |+["VERB", "AUX", "PRON", "ADP", "DET"] +29 29 | ' 1 2 3 '.split() +30 30 | '1<>2<>3<4'.split('<>') +31 31 | -SIM905.py:36:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:29:1: SIM905 [*] Consider using a list literal instead of `str.split` | -34 | "a,b,c,d".split(maxsplit=0) -35 | "VERB AUX PRON ADP DET".split(" ") -36 | ' 1 2 3 '.split() +27 | "a,b,c,d".split(maxsplit=0) +28 | "VERB AUX PRON ADP DET".split(" ") +29 | ' 1 2 3 '.split() | ^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -37 | '1<>2<>3<4'.split('<>') +30 | '1<>2<>3<4'.split('<>') | = help: Replace with list literal ℹ Safe fix -33 33 | "a,b,c,d".split(maxsplit=1) -34 34 | "a,b,c,d".split(maxsplit=0) -35 35 | "VERB AUX PRON ADP DET".split(" ") -36 |-' 1 2 3 '.split() - 36 |+['1', '2', '3'] -37 37 | '1<>2<>3<4'.split('<>') -38 38 | -39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +26 26 | "a,b,c,d".split(maxsplit=1) +27 27 | "a,b,c,d".split(maxsplit=0) +28 28 | "VERB AUX PRON ADP DET".split(" ") +29 |-' 1 2 3 '.split() + 29 |+['1', '2', '3'] +30 30 | '1<>2<>3<4'.split('<>') +31 31 | +32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -SIM905.py:37:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:30:1: SIM905 [*] Consider using a list literal instead of `str.split` | -35 | "VERB AUX PRON ADP DET".split(" ") -36 | ' 1 2 3 '.split() -37 | '1<>2<>3<4'.split('<>') +28 | "VERB AUX PRON ADP DET".split(" ") +29 | ' 1 2 3 '.split() +30 | '1<>2<>3<4'.split('<>') | ^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -38 | -39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +31 | +32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] | = help: Replace with list literal ℹ Safe fix -34 34 | "a,b,c,d".split(maxsplit=0) -35 35 | "VERB AUX PRON ADP DET".split(" ") -36 36 | ' 1 2 3 '.split() -37 |-'1<>2<>3<4'.split('<>') - 37 |+['1', '2', '3<4'] -38 38 | -39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -40 40 | "".split() # [] +27 27 | "a,b,c,d".split(maxsplit=0) +28 28 | "VERB AUX PRON ADP DET".split(" ") +29 29 | ' 1 2 3 '.split() +30 |-'1<>2<>3<4'.split('<>') + 30 |+['1', '2', '3<4'] +31 31 | +32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +33 33 | "".split() # [] -SIM905.py:39:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:32:1: SIM905 [*] Consider using a list literal instead of `str.split` | -37 | '1<>2<>3<4'.split('<>') -38 | -39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +30 | '1<>2<>3<4'.split('<>') +31 | +32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -40 | "".split() # [] -41 | """ +33 | "".split() # [] +34 | """ | = help: Replace with list literal ℹ Safe fix -36 36 | ' 1 2 3 '.split() -37 37 | '1<>2<>3<4'.split('<>') -38 38 | -39 |-" a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] - 39 |+[" a", "a a", "a a "] # [" a", "a a", "a a "] -40 40 | "".split() # [] -41 41 | """ -42 42 | """.split() # [] +29 29 | ' 1 2 3 '.split() +30 30 | '1<>2<>3<4'.split('<>') +31 31 | +32 |-" a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] + 32 |+[" a", "a a", "a a "] # [" a", "a a", "a a "] +33 33 | "".split() # [] +34 34 | """ +35 35 | """.split() # [] -SIM905.py:40:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:33:1: SIM905 [*] Consider using a list literal instead of `str.split` | -39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -40 | "".split() # [] +32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +33 | "".split() # [] | ^^^^^^^^^^ SIM905 -41 | """ -42 | """.split() # [] +34 | """ +35 | """.split() # [] | = help: Replace with list literal ℹ Safe fix -37 37 | '1<>2<>3<4'.split('<>') -38 38 | -39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -40 |-"".split() # [] - 40 |+[] # [] -41 41 | """ -42 42 | """.split() # [] -43 43 | " ".split() # [] +30 30 | '1<>2<>3<4'.split('<>') +31 31 | +32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +33 |-"".split() # [] + 33 |+[] # [] +34 34 | """ +35 35 | """.split() # [] +36 36 | " ".split() # [] -SIM905.py:41:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:34:1: SIM905 [*] Consider using a list literal instead of `str.split` | -39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -40 | "".split() # [] -41 | / """ -42 | | """.split() # [] +32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +33 | "".split() # [] +34 | / """ +35 | | """.split() # [] | |___________^ SIM905 -43 | " ".split() # [] -44 | "/abc/".split() # ["/abc/"] +36 | " ".split() # [] +37 | "/abc/".split() # ["/abc/"] | = help: Replace with list literal ℹ Safe fix -38 38 | -39 39 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] -40 40 | "".split() # [] -41 |-""" -42 |-""".split() # [] - 41 |+[] # [] -43 42 | " ".split() # [] -44 43 | "/abc/".split() # ["/abc/"] -45 44 | ("a,b,c" +31 31 | +32 32 | " a*a a*a a ".split("*", -1) # [" a", "a a", "a a "] +33 33 | "".split() # [] +34 |-""" +35 |-""".split() # [] + 34 |+[] # [] +36 35 | " ".split() # [] +37 36 | "/abc/".split() # ["/abc/"] +38 37 | ("a,b,c" -SIM905.py:43:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:36:1: SIM905 [*] Consider using a list literal instead of `str.split` | -41 | """ -42 | """.split() # [] -43 | " ".split() # [] +34 | """ +35 | """.split() # [] +36 | " ".split() # [] | ^^^^^^^^^^^^^^^^^ SIM905 -44 | "/abc/".split() # ["/abc/"] -45 | ("a,b,c" +37 | "/abc/".split() # ["/abc/"] +38 | ("a,b,c" | = help: Replace with list literal ℹ Safe fix -40 40 | "".split() # [] -41 41 | """ -42 42 | """.split() # [] -43 |-" ".split() # [] - 43 |+[] # [] -44 44 | "/abc/".split() # ["/abc/"] -45 45 | ("a,b,c" -46 46 | # comment +33 33 | "".split() # [] +34 34 | """ +35 35 | """.split() # [] +36 |-" ".split() # [] + 36 |+[] # [] +37 37 | "/abc/".split() # ["/abc/"] +38 38 | ("a,b,c" +39 39 | # comment -SIM905.py:44:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:37:1: SIM905 [*] Consider using a list literal instead of `str.split` | -42 | """.split() # [] -43 | " ".split() # [] -44 | "/abc/".split() # ["/abc/"] +35 | """.split() # [] +36 | " ".split() # [] +37 | "/abc/".split() # ["/abc/"] | ^^^^^^^^^^^^^^^ SIM905 -45 | ("a,b,c" -46 | # comment +38 | ("a,b,c" +39 | # comment | = help: Replace with list literal ℹ Safe fix -41 41 | """ -42 42 | """.split() # [] -43 43 | " ".split() # [] -44 |-"/abc/".split() # ["/abc/"] - 44 |+["/abc/"] # ["/abc/"] -45 45 | ("a,b,c" -46 46 | # comment -47 47 | .split() +34 34 | """ +35 35 | """.split() # [] +36 36 | " ".split() # [] +37 |-"/abc/".split() # ["/abc/"] + 37 |+["/abc/"] # ["/abc/"] +38 38 | ("a,b,c" +39 39 | # comment +40 40 | .split() -SIM905.py:45:2: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:38:2: SIM905 [*] Consider using a list literal instead of `str.split` | -43 | " ".split() # [] -44 | "/abc/".split() # ["/abc/"] -45 | ("a,b,c" +36 | " ".split() # [] +37 | "/abc/".split() # ["/abc/"] +38 | ("a,b,c" | __^ -46 | | # comment -47 | | .split() +39 | | # comment +40 | | .split() | |________^ SIM905 -48 | ) # ["a,b,c"] -49 | ("a,b,c" +41 | ) # ["a,b,c"] +42 | ("a,b,c" | = help: Replace with list literal ℹ Unsafe fix -42 42 | """.split() # [] -43 43 | " ".split() # [] -44 44 | "/abc/".split() # ["/abc/"] -45 |-("a,b,c" -46 |-# comment -47 |-.split() - 45 |+(["a,b,c"] -48 46 | ) # ["a,b,c"] -49 47 | ("a,b,c" -50 48 | # comment1 - -SIM905.py:49:2: SIM905 [*] Consider using a list literal instead of `str.split` - | -47 | .split() -48 | ) # ["a,b,c"] -49 | ("a,b,c" +35 35 | """.split() # [] +36 36 | " ".split() # [] +37 37 | "/abc/".split() # ["/abc/"] +38 |-("a,b,c" +39 |-# comment +40 |-.split() + 38 |+(["a,b,c"] +41 39 | ) # ["a,b,c"] +42 40 | ("a,b,c" +43 41 | # comment1 + +SIM905.py:42:2: SIM905 [*] Consider using a list literal instead of `str.split` + | +40 | .split() +41 | ) # ["a,b,c"] +42 | ("a,b,c" | __^ -50 | | # comment1 -51 | | .split(",") +43 | | # comment1 +44 | | .split(",") | |___________^ SIM905 -52 | ) # ["a", "b", "c"] -53 | ("a," +45 | ) # ["a", "b", "c"] +46 | ("a," | = help: Replace with list literal ℹ Unsafe fix -46 46 | # comment -47 47 | .split() -48 48 | ) # ["a,b,c"] -49 |-("a,b,c" -50 |-# comment1 -51 |-.split(",") - 49 |+(["a", "b", "c"] -52 50 | ) # ["a", "b", "c"] -53 51 | ("a," -54 52 | # comment - -SIM905.py:53:2: SIM905 [*] Consider using a list literal instead of `str.split` - | -51 | .split(",") -52 | ) # ["a", "b", "c"] -53 | ("a," +39 39 | # comment +40 40 | .split() +41 41 | ) # ["a,b,c"] +42 |-("a,b,c" +43 |-# comment1 +44 |-.split(",") + 42 |+(["a", "b", "c"] +45 43 | ) # ["a", "b", "c"] +46 44 | ("a," +47 45 | # comment + +SIM905.py:46:2: SIM905 [*] Consider using a list literal instead of `str.split` + | +44 | .split(",") +45 | ) # ["a", "b", "c"] +46 | ("a," | __^ -54 | | # comment -55 | | "b," -56 | | "c" -57 | | .split(",") +47 | | # comment +48 | | "b," +49 | | "c" +50 | | .split(",") | |___________^ SIM905 -58 | ) # ["a", "b", "c"] +51 | ) # ["a", "b", "c"] | = help: Replace with list literal ℹ Unsafe fix -50 50 | # comment1 -51 51 | .split(",") -52 52 | ) # ["a", "b", "c"] -53 |-("a," -54 |-# comment -55 |-"b," -56 |-"c" -57 |-.split(",") - 53 |+(["a", "b", "c"] -58 54 | ) # ["a", "b", "c"] -59 55 | -60 56 | "hello "\ - -SIM905.py:60:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -58 | ) # ["a", "b", "c"] -59 | -60 | / "hello "\ -61 | | "world".split() +43 43 | # comment1 +44 44 | .split(",") +45 45 | ) # ["a", "b", "c"] +46 |-("a," +47 |-# comment +48 |-"b," +49 |-"c" +50 |-.split(",") + 46 |+(["a", "b", "c"] +51 47 | ) # ["a", "b", "c"] +52 48 | +53 49 | "hello "\ + +SIM905.py:53:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +51 | ) # ["a", "b", "c"] +52 | +53 | / "hello "\ +54 | | "world".split() | |___________________^ SIM905 -62 | # ["hello", "world"] +55 | # ["hello", "world"] | = help: Replace with list literal ℹ Safe fix -57 57 | .split(",") -58 58 | ) # ["a", "b", "c"] -59 59 | -60 |-"hello "\ -61 |- "world".split() - 60 |+["hello", "world"] -62 61 | # ["hello", "world"] -63 62 | -64 63 | # prefixes and isc +50 50 | .split(",") +51 51 | ) # ["a", "b", "c"] +52 52 | +53 |-"hello "\ +54 |- "world".split() + 53 |+["hello", "world"] +55 54 | # ["hello", "world"] +56 55 | +57 56 | # prefixes and isc -SIM905.py:65:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:58:1: SIM905 [*] Consider using a list literal instead of `str.split` | -64 | # prefixes and isc -65 | u"a b".split() # [u"a", u"b"] +57 | # prefixes and isc +58 | u"a b".split() # [u"a", u"b"] | ^^^^^^^^^^^^^^ SIM905 -66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 | ("a " "b").split() # ["a", "b"] +59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 | ("a " "b").split() # ["a", "b"] | = help: Replace with list literal ℹ Safe fix -62 62 | # ["hello", "world"] -63 63 | -64 64 | # prefixes and isc -65 |-u"a b".split() # [u"a", u"b"] - 65 |+[u"a", u"b"] # [u"a", u"b"] -66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 67 | ("a " "b").split() # ["a", "b"] -68 68 | "a " "b".split() # ["a", "b"] +55 55 | # ["hello", "world"] +56 56 | +57 57 | # prefixes and isc +58 |-u"a b".split() # [u"a", u"b"] + 58 |+[u"a", u"b"] # [u"a", u"b"] +59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 60 | ("a " "b").split() # ["a", "b"] +61 61 | "a " "b".split() # ["a", "b"] -SIM905.py:66:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:59:1: SIM905 [*] Consider using a list literal instead of `str.split` | -64 | # prefixes and isc -65 | u"a b".split() # [u"a", u"b"] -66 | r"a \n b".split() # [r"a", r"\n", r"b"] +57 | # prefixes and isc +58 | u"a b".split() # [u"a", u"b"] +59 | r"a \n b".split() # [r"a", r"\n", r"b"] | ^^^^^^^^^^^^^^^^^ SIM905 -67 | ("a " "b").split() # ["a", "b"] -68 | "a " "b".split() # ["a", "b"] +60 | ("a " "b").split() # ["a", "b"] +61 | "a " "b".split() # ["a", "b"] | = help: Replace with list literal ℹ Safe fix -63 63 | -64 64 | # prefixes and isc -65 65 | u"a b".split() # [u"a", u"b"] -66 |-r"a \n b".split() # [r"a", r"\n", r"b"] - 66 |+[r"a", r"\n", r"b"] # [r"a", r"\n", r"b"] -67 67 | ("a " "b").split() # ["a", "b"] -68 68 | "a " "b".split() # ["a", "b"] -69 69 | u"a " "b".split() # [u"a", u"b"] +56 56 | +57 57 | # prefixes and isc +58 58 | u"a b".split() # [u"a", u"b"] +59 |-r"a \n b".split() # [r"a", r"\n", r"b"] + 59 |+[r"a", r"\n", r"b"] # [r"a", r"\n", r"b"] +60 60 | ("a " "b").split() # ["a", "b"] +61 61 | "a " "b".split() # ["a", "b"] +62 62 | u"a " "b".split() # [u"a", u"b"] -SIM905.py:67:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:60:1: SIM905 [*] Consider using a list literal instead of `str.split` | -65 | u"a b".split() # [u"a", u"b"] -66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 | ("a " "b").split() # ["a", "b"] +58 | u"a b".split() # [u"a", u"b"] +59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 | ("a " "b").split() # ["a", "b"] | ^^^^^^^^^^^^^^^^^^ SIM905 -68 | "a " "b".split() # ["a", "b"] -69 | u"a " "b".split() # [u"a", u"b"] +61 | "a " "b".split() # ["a", "b"] +62 | u"a " "b".split() # [u"a", u"b"] | = help: Replace with list literal ℹ Safe fix -64 64 | # prefixes and isc -65 65 | u"a b".split() # [u"a", u"b"] -66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 |-("a " "b").split() # ["a", "b"] - 67 |+["a", "b"] # ["a", "b"] -68 68 | "a " "b".split() # ["a", "b"] -69 69 | u"a " "b".split() # [u"a", u"b"] -70 70 | "a " u"b".split() # ["a", "b"] +57 57 | # prefixes and isc +58 58 | u"a b".split() # [u"a", u"b"] +59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 |-("a " "b").split() # ["a", "b"] + 60 |+["a", "b"] # ["a", "b"] +61 61 | "a " "b".split() # ["a", "b"] +62 62 | u"a " "b".split() # [u"a", u"b"] +63 63 | "a " u"b".split() # ["a", "b"] -SIM905.py:68:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:61:1: SIM905 [*] Consider using a list literal instead of `str.split` | -66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 | ("a " "b").split() # ["a", "b"] -68 | "a " "b".split() # ["a", "b"] +59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 | ("a " "b").split() # ["a", "b"] +61 | "a " "b".split() # ["a", "b"] | ^^^^^^^^^^^^^^^^ SIM905 -69 | u"a " "b".split() # [u"a", u"b"] -70 | "a " u"b".split() # ["a", "b"] +62 | u"a " "b".split() # [u"a", u"b"] +63 | "a " u"b".split() # ["a", "b"] | = help: Replace with list literal ℹ Safe fix -65 65 | u"a b".split() # [u"a", u"b"] -66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 67 | ("a " "b").split() # ["a", "b"] -68 |-"a " "b".split() # ["a", "b"] - 68 |+["a", "b"] # ["a", "b"] -69 69 | u"a " "b".split() # [u"a", u"b"] -70 70 | "a " u"b".split() # ["a", "b"] -71 71 | u"a " r"\n".split() # [u"a", u"\\n"] +58 58 | u"a b".split() # [u"a", u"b"] +59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 60 | ("a " "b").split() # ["a", "b"] +61 |-"a " "b".split() # ["a", "b"] + 61 |+["a", "b"] # ["a", "b"] +62 62 | u"a " "b".split() # [u"a", u"b"] +63 63 | "a " u"b".split() # ["a", "b"] +64 64 | u"a " r"\n".split() # [u"a", u"\\n"] -SIM905.py:69:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:62:1: SIM905 [*] Consider using a list literal instead of `str.split` | -67 | ("a " "b").split() # ["a", "b"] -68 | "a " "b".split() # ["a", "b"] -69 | u"a " "b".split() # [u"a", u"b"] +60 | ("a " "b").split() # ["a", "b"] +61 | "a " "b".split() # ["a", "b"] +62 | u"a " "b".split() # [u"a", u"b"] | ^^^^^^^^^^^^^^^^^ SIM905 -70 | "a " u"b".split() # ["a", "b"] -71 | u"a " r"\n".split() # [u"a", u"\\n"] +63 | "a " u"b".split() # ["a", "b"] +64 | u"a " r"\n".split() # [u"a", u"\\n"] | = help: Replace with list literal ℹ Safe fix -66 66 | r"a \n b".split() # [r"a", r"\n", r"b"] -67 67 | ("a " "b").split() # ["a", "b"] -68 68 | "a " "b".split() # ["a", "b"] -69 |-u"a " "b".split() # [u"a", u"b"] - 69 |+[u"a", u"b"] # [u"a", u"b"] -70 70 | "a " u"b".split() # ["a", "b"] -71 71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 72 | r"\n " u"\n".split() # [r"\n"] +59 59 | r"a \n b".split() # [r"a", r"\n", r"b"] +60 60 | ("a " "b").split() # ["a", "b"] +61 61 | "a " "b".split() # ["a", "b"] +62 |-u"a " "b".split() # [u"a", u"b"] + 62 |+[u"a", u"b"] # [u"a", u"b"] +63 63 | "a " u"b".split() # ["a", "b"] +64 64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 65 | r"\n " u"\n".split() # [r"\n"] -SIM905.py:70:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:63:1: SIM905 [*] Consider using a list literal instead of `str.split` | -68 | "a " "b".split() # ["a", "b"] -69 | u"a " "b".split() # [u"a", u"b"] -70 | "a " u"b".split() # ["a", "b"] +61 | "a " "b".split() # ["a", "b"] +62 | u"a " "b".split() # [u"a", u"b"] +63 | "a " u"b".split() # ["a", "b"] | ^^^^^^^^^^^^^^^^^ SIM905 -71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 | r"\n " u"\n".split() # [r"\n"] +64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 | r"\n " u"\n".split() # [r"\n"] | = help: Replace with list literal ℹ Safe fix -67 67 | ("a " "b").split() # ["a", "b"] -68 68 | "a " "b".split() # ["a", "b"] -69 69 | u"a " "b".split() # [u"a", u"b"] -70 |-"a " u"b".split() # ["a", "b"] - 70 |+["a", "b"] # ["a", "b"] -71 71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 72 | r"\n " u"\n".split() # [r"\n"] -73 73 | r"\n " "\n".split() # [r"\n"] +60 60 | ("a " "b").split() # ["a", "b"] +61 61 | "a " "b".split() # ["a", "b"] +62 62 | u"a " "b".split() # [u"a", u"b"] +63 |-"a " u"b".split() # ["a", "b"] + 63 |+["a", "b"] # ["a", "b"] +64 64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 65 | r"\n " u"\n".split() # [r"\n"] +66 66 | r"\n " "\n".split() # [r"\n"] -SIM905.py:71:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:64:1: SIM905 [*] Consider using a list literal instead of `str.split` | -69 | u"a " "b".split() # [u"a", u"b"] -70 | "a " u"b".split() # ["a", "b"] -71 | u"a " r"\n".split() # [u"a", u"\\n"] +62 | u"a " "b".split() # [u"a", u"b"] +63 | "a " u"b".split() # ["a", "b"] +64 | u"a " r"\n".split() # [u"a", u"\\n"] | ^^^^^^^^^^^^^^^^^^^ SIM905 -72 | r"\n " u"\n".split() # [r"\n"] -73 | r"\n " "\n".split() # [r"\n"] +65 | r"\n " u"\n".split() # [r"\n"] +66 | r"\n " "\n".split() # [r"\n"] | = help: Replace with list literal ℹ Safe fix -68 68 | "a " "b".split() # ["a", "b"] -69 69 | u"a " "b".split() # [u"a", u"b"] -70 70 | "a " u"b".split() # ["a", "b"] -71 |-u"a " r"\n".split() # [u"a", u"\\n"] - 71 |+[u"a", u"\\n"] # [u"a", u"\\n"] -72 72 | r"\n " u"\n".split() # [r"\n"] -73 73 | r"\n " "\n".split() # [r"\n"] -74 74 | "a " r"\n".split() # ["a", "\\n"] +61 61 | "a " "b".split() # ["a", "b"] +62 62 | u"a " "b".split() # [u"a", u"b"] +63 63 | "a " u"b".split() # ["a", "b"] +64 |-u"a " r"\n".split() # [u"a", u"\\n"] + 64 |+[u"a", u"\\n"] # [u"a", u"\\n"] +65 65 | r"\n " u"\n".split() # [r"\n"] +66 66 | r"\n " "\n".split() # [r"\n"] +67 67 | "a " r"\n".split() # ["a", "\\n"] -SIM905.py:72:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:65:1: SIM905 [*] Consider using a list literal instead of `str.split` | -70 | "a " u"b".split() # ["a", "b"] -71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 | r"\n " u"\n".split() # [r"\n"] +63 | "a " u"b".split() # ["a", "b"] +64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 | r"\n " u"\n".split() # [r"\n"] | ^^^^^^^^^^^^^^^^^^^^ SIM905 -73 | r"\n " "\n".split() # [r"\n"] -74 | "a " r"\n".split() # ["a", "\\n"] +66 | r"\n " "\n".split() # [r"\n"] +67 | "a " r"\n".split() # ["a", "\\n"] | = help: Replace with list literal ℹ Safe fix -69 69 | u"a " "b".split() # [u"a", u"b"] -70 70 | "a " u"b".split() # ["a", "b"] -71 71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 |-r"\n " u"\n".split() # [r"\n"] - 72 |+[r"\n"] # [r"\n"] -73 73 | r"\n " "\n".split() # [r"\n"] -74 74 | "a " r"\n".split() # ["a", "\\n"] -75 75 | +62 62 | u"a " "b".split() # [u"a", u"b"] +63 63 | "a " u"b".split() # ["a", "b"] +64 64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 |-r"\n " u"\n".split() # [r"\n"] + 65 |+[r"\n"] # [r"\n"] +66 66 | r"\n " "\n".split() # [r"\n"] +67 67 | "a " r"\n".split() # ["a", "\\n"] +68 68 | -SIM905.py:73:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:66:1: SIM905 [*] Consider using a list literal instead of `str.split` | -71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 | r"\n " u"\n".split() # [r"\n"] -73 | r"\n " "\n".split() # [r"\n"] +64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 | r"\n " u"\n".split() # [r"\n"] +66 | r"\n " "\n".split() # [r"\n"] | ^^^^^^^^^^^^^^^^^^^ SIM905 -74 | "a " r"\n".split() # ["a", "\\n"] +67 | "a " r"\n".split() # ["a", "\\n"] | = help: Replace with list literal ℹ Safe fix -70 70 | "a " u"b".split() # ["a", "b"] -71 71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 72 | r"\n " u"\n".split() # [r"\n"] -73 |-r"\n " "\n".split() # [r"\n"] - 73 |+[r"\n"] # [r"\n"] -74 74 | "a " r"\n".split() # ["a", "\\n"] -75 75 | -76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +63 63 | "a " u"b".split() # ["a", "b"] +64 64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 65 | r"\n " u"\n".split() # [r"\n"] +66 |-r"\n " "\n".split() # [r"\n"] + 66 |+[r"\n"] # [r"\n"] +67 67 | "a " r"\n".split() # ["a", "\\n"] +68 68 | +69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -SIM905.py:74:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:67:1: SIM905 [*] Consider using a list literal instead of `str.split` | -72 | r"\n " u"\n".split() # [r"\n"] -73 | r"\n " "\n".split() # [r"\n"] -74 | "a " r"\n".split() # ["a", "\\n"] +65 | r"\n " u"\n".split() # [r"\n"] +66 | r"\n " "\n".split() # [r"\n"] +67 | "a " r"\n".split() # ["a", "\\n"] | ^^^^^^^^^^^^^^^^^^ SIM905 -75 | -76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +68 | +69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] | = help: Replace with list literal ℹ Safe fix -71 71 | u"a " r"\n".split() # [u"a", u"\\n"] -72 72 | r"\n " u"\n".split() # [r"\n"] -73 73 | r"\n " "\n".split() # [r"\n"] -74 |-"a " r"\n".split() # ["a", "\\n"] - 74 |+["a", "\\n"] # ["a", "\\n"] -75 75 | -76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +64 64 | u"a " r"\n".split() # [u"a", u"\\n"] +65 65 | r"\n " u"\n".split() # [r"\n"] +66 66 | r"\n " "\n".split() # [r"\n"] +67 |-"a " r"\n".split() # ["a", "\\n"] + 67 |+["a", "\\n"] # ["a", "\\n"] +68 68 | +69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -SIM905.py:76:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:69:1: SIM905 [*] Consider using a list literal instead of `str.split` | -74 | "a " r"\n".split() # ["a", "\\n"] -75 | -76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +67 | "a " r"\n".split() # ["a", "\\n"] +68 | +69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] | = help: Replace with list literal ℹ Safe fix -73 73 | r"\n " "\n".split() # [r"\n"] -74 74 | "a " r"\n".split() # ["a", "\\n"] -75 75 | -76 |-"a,b,c".split(',', maxsplit=0) # ["a,b,c"] - 76 |+["a,b,c"] # ["a,b,c"] -77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -78 78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -79 79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +66 66 | r"\n " "\n".split() # [r"\n"] +67 67 | "a " r"\n".split() # ["a", "\\n"] +68 68 | +69 |-"a,b,c".split(',', maxsplit=0) # ["a,b,c"] + 69 |+["a,b,c"] # ["a,b,c"] +70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +72 72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] -SIM905.py:77:1: SIM905 [*] Consider using a list literal instead of `str.split` +SIM905.py:70:1: SIM905 [*] Consider using a list literal instead of `str.split` | -76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] | = help: Replace with list literal ℹ Safe fix -74 74 | "a " r"\n".split() # ["a", "\\n"] -75 75 | -76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -77 |-"a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] - 77 |+["a", "b", "c"] # ["a", "b", "c"] -78 78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -79 79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] -80 80 | - -SIM905.py:78:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +67 67 | "a " r"\n".split() # ["a", "\\n"] +68 68 | +69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 |-"a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] + 70 |+["a", "b", "c"] # ["a", "b", "c"] +71 71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +72 72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +73 73 | + +SIM905.py:71:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] | = help: Replace with list literal ℹ Safe fix -75 75 | -76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -78 |-"a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] - 78 |+["a", "b", "c"] # ["a", "b", "c"] -79 79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] -80 80 | -81 81 | # negatives - -SIM905.py:79:1: SIM905 [*] Consider using a list literal instead of `str.split` - | -77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -79 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +68 68 | +69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 |-"a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] + 71 |+["a", "b", "c"] # ["a", "b", "c"] +72 72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] +73 73 | +74 74 | # negatives + +SIM905.py:72:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +72 | "a,b,c".split(',', maxsplit=-0) # ["a,b,c"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905 -80 | -81 | # negatives +73 | +74 | # negatives | = help: Replace with list literal ℹ Safe fix -76 76 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] -77 77 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] -78 78 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] -79 |-"a,b,c".split(',', maxsplit=-0) # ["a,b,c"] - 79 |+["a,b,c"] # ["a,b,c"] -80 80 | -81 81 | # negatives -82 82 | +69 69 | "a,b,c".split(',', maxsplit=0) # ["a,b,c"] +70 70 | "a,b,c".split(',', maxsplit=-1) # ["a", "b", "c"] +71 71 | "a,b,c".split(',', maxsplit=-2) # ["a", "b", "c"] +72 |-"a,b,c".split(',', maxsplit=-0) # ["a,b,c"] + 72 |+["a,b,c"] # ["a,b,c"] +73 73 | +74 74 | # negatives +75 75 | + +SIM905.py:103:1: SIM905 [*] Consider using a list literal instead of `str.split` + | +102 | # another positive demonstrating quote preservation +103 | / """ +104 | | "itemA" +105 | | 'itemB' +106 | | '''itemC''' +107 | | "'itemD'" +108 | | """.split() + | |___________^ SIM905 + | + = help: Replace with list literal + +ℹ Safe fix +100 100 | +101 101 | +102 102 | # another positive demonstrating quote preservation +103 |-""" +104 |-"itemA" +105 |-'itemB' +106 |-'''itemC''' +107 |-"'itemD'" +108 |-""".split() + 103 |+['"itemA"', "'itemB'", "'''itemC'''", "\"'itemD'\""]