mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
[flake8-simplify
] Fix raw string handling in SIM905
for embedded quotes (#19591)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / mkdocs (push) Waiting to run
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / mkdocs (push) Waiting to run
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
## Summary When splitting triple-quoted, raw strings one has to take care before attempting to make each item have single-quotes. Fixes #19577 --------- Co-authored-by: dylwil3 <dylwil3@gmail.com>
This commit is contained in:
parent
134435415e
commit
1a368b0bf9
3 changed files with 158 additions and 12 deletions
|
@ -129,4 +129,35 @@ print(" x ".rsplit(maxsplit=0))
|
|||
print(" x ".rsplit(maxsplit=0))
|
||||
print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
print(" x ".rsplit(maxsplit=0))
|
||||
print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
|
||||
# https://github.com/astral-sh/ruff/issues/19581 - embedded quotes in raw strings
|
||||
r"""simple@example.com
|
||||
very.common@example.com
|
||||
FirstName.LastName@EasierReading.org
|
||||
x@example.com
|
||||
long.email-address-with-hyphens@and.subdomains.example.com
|
||||
user.name+tag+sorting@example.com
|
||||
name/surname@example.com
|
||||
xample@s.example
|
||||
" "@example.org
|
||||
"john..doe"@example.org
|
||||
mailhost!username@example.org
|
||||
"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
|
||||
user%example.com@example.org
|
||||
user-@example.org
|
||||
I❤️CHOCOLATE@example.com
|
||||
this\ still\"not\\allowed@example.com
|
||||
stellyamburrr985@example.com
|
||||
Abc.123@example.com
|
||||
user+mailbox/department=shipping@example.com
|
||||
!#$%&'*+-/=?^_`.{|}~@example.com
|
||||
"Abc@def"@example.com
|
||||
"Fred\ Bloggs"@example.com
|
||||
"Joe.\\Blow"@example.com""".split("\n")
|
||||
|
||||
|
||||
r"""first
|
||||
'no need' to escape
|
||||
"swap" quote style
|
||||
"use' ugly triple quotes""".split("\n")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::cmp::Ordering;
|
||||
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::StringFlags;
|
||||
use ruff_python_ast::{
|
||||
Expr, ExprCall, ExprContext, ExprList, ExprUnaryOp, StringLiteral, StringLiteralFlags,
|
||||
StringLiteralValue, UnaryOp, str::TripleQuotes,
|
||||
|
@ -116,26 +117,50 @@ pub(crate) fn split_static_string(
|
|||
}
|
||||
}
|
||||
|
||||
fn replace_flags(elt: &str, flags: StringLiteralFlags) -> StringLiteralFlags {
|
||||
// In the ideal case we can wrap the element in _single_ quotes of the same
|
||||
// style. For example, both of these are okay:
|
||||
//
|
||||
// ```python
|
||||
// """itemA
|
||||
// itemB
|
||||
// itemC""".split() # -> ["itemA", "itemB", "itemC"]
|
||||
// ```
|
||||
//
|
||||
// ```python
|
||||
// r"""itemA
|
||||
// 'single'quoted
|
||||
// """.split() # -> [r"itemA",r"'single'quoted'"]
|
||||
// ```
|
||||
if !flags.prefix().is_raw() || !elt.contains(flags.quote_style().as_char()) {
|
||||
flags.with_triple_quotes(TripleQuotes::No)
|
||||
}
|
||||
// If we have a raw string containing a quotation mark of the same style,
|
||||
// then we have to swap the style of quotation marks used
|
||||
else if !elt.contains(flags.quote_style().opposite().as_char()) {
|
||||
flags
|
||||
.with_quote_style(flags.quote_style().opposite())
|
||||
.with_triple_quotes(TripleQuotes::No)
|
||||
} else
|
||||
// If both types of quotes are used in the raw, triple-quoted string, then
|
||||
// we are forced to either add escapes or keep the triple quotes. We opt for
|
||||
// the latter.
|
||||
{
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
||||
fn construct_replacement(elts: &[&str], flags: StringLiteralFlags) -> Expr {
|
||||
Expr::List(ExprList {
|
||||
elts: elts
|
||||
.iter()
|
||||
.map(|elt| {
|
||||
let element_flags = replace_flags(elt, flags);
|
||||
Expr::from(StringLiteral {
|
||||
value: Box::from(*elt),
|
||||
range: TextRange::default(),
|
||||
node_index: ruff_python_ast::AtomicNodeIndex::dummy(),
|
||||
// intentionally omit the triple quote flag, if set, to avoid strange
|
||||
// replacements like
|
||||
//
|
||||
// ```python
|
||||
// """
|
||||
// itemA
|
||||
// itemB
|
||||
// itemC
|
||||
// """.split() # -> ["""itemA""", """itemB""", """itemC"""]
|
||||
// ```
|
||||
flags: flags.with_triple_quotes(TripleQuotes::No),
|
||||
flags: element_flags,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
|
|
|
@ -1226,6 +1226,7 @@ SIM905.py:130:7: SIM905 [*] Consider using a list literal instead of `str.split`
|
|||
130 |+print([" x"])
|
||||
131 131 | print(" x ".rsplit(maxsplit=0))
|
||||
132 132 | print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
133 133 |
|
||||
|
||||
SIM905.py:131:7: SIM905 [*] Consider using a list literal instead of `str.split`
|
||||
|
|
||||
|
@ -1244,6 +1245,8 @@ SIM905.py:131:7: SIM905 [*] Consider using a list literal instead of `str.split`
|
|||
131 |-print(" x ".rsplit(maxsplit=0))
|
||||
131 |+print([" x"])
|
||||
132 132 | print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
133 133 |
|
||||
134 134 | # https://github.com/astral-sh/ruff/issues/19581 - embedded quotes in raw strings
|
||||
|
||||
SIM905.py:132:7: SIM905 [*] Consider using a list literal instead of `str.split`
|
||||
|
|
||||
|
@ -1251,6 +1254,8 @@ SIM905.py:132:7: SIM905 [*] Consider using a list literal instead of `str.split`
|
|||
131 | print(" x ".rsplit(maxsplit=0))
|
||||
132 | print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM905
|
||||
133 |
|
||||
134 | # https://github.com/astral-sh/ruff/issues/19581 - embedded quotes in raw strings
|
||||
|
|
||||
= help: Replace with list literal
|
||||
|
||||
|
@ -1260,3 +1265,88 @@ SIM905.py:132:7: SIM905 [*] Consider using a list literal instead of `str.split`
|
|||
131 131 | print(" x ".rsplit(maxsplit=0))
|
||||
132 |-print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
132 |+print([" x"])
|
||||
133 133 |
|
||||
134 134 | # https://github.com/astral-sh/ruff/issues/19581 - embedded quotes in raw strings
|
||||
135 135 | r"""simple@example.com
|
||||
|
||||
SIM905.py:135:1: SIM905 [*] Consider using a list literal instead of `str.split`
|
||||
|
|
||||
134 | # https://github.com/astral-sh/ruff/issues/19581 - embedded quotes in raw strings
|
||||
135 | / r"""simple@example.com
|
||||
136 | | very.common@example.com
|
||||
137 | | FirstName.LastName@EasierReading.org
|
||||
138 | | x@example.com
|
||||
139 | | long.email-address-with-hyphens@and.subdomains.example.com
|
||||
140 | | user.name+tag+sorting@example.com
|
||||
141 | | name/surname@example.com
|
||||
142 | | xample@s.example
|
||||
143 | | " "@example.org
|
||||
144 | | "john..doe"@example.org
|
||||
145 | | mailhost!username@example.org
|
||||
146 | | "very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
|
||||
147 | | user%example.com@example.org
|
||||
148 | | user-@example.org
|
||||
149 | | I❤️CHOCOLATE@example.com
|
||||
150 | | this\ still\"not\\allowed@example.com
|
||||
151 | | stellyamburrr985@example.com
|
||||
152 | | Abc.123@example.com
|
||||
153 | | user+mailbox/department=shipping@example.com
|
||||
154 | | !#$%&'*+-/=?^_`.{|}~@example.com
|
||||
155 | | "Abc@def"@example.com
|
||||
156 | | "Fred\ Bloggs"@example.com
|
||||
157 | | "Joe.\\Blow"@example.com""".split("\n")
|
||||
| |_______________________________________^ SIM905
|
||||
|
|
||||
= help: Replace with list literal
|
||||
|
||||
ℹ Safe fix
|
||||
132 132 | print(" x ".rsplit(sep=None, maxsplit=0))
|
||||
133 133 |
|
||||
134 134 | # https://github.com/astral-sh/ruff/issues/19581 - embedded quotes in raw strings
|
||||
135 |-r"""simple@example.com
|
||||
136 |-very.common@example.com
|
||||
137 |-FirstName.LastName@EasierReading.org
|
||||
138 |-x@example.com
|
||||
139 |-long.email-address-with-hyphens@and.subdomains.example.com
|
||||
140 |-user.name+tag+sorting@example.com
|
||||
141 |-name/surname@example.com
|
||||
142 |-xample@s.example
|
||||
143 |-" "@example.org
|
||||
144 |-"john..doe"@example.org
|
||||
145 |-mailhost!username@example.org
|
||||
146 |-"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
|
||||
147 |-user%example.com@example.org
|
||||
148 |-user-@example.org
|
||||
149 |-I❤️CHOCOLATE@example.com
|
||||
150 |-this\ still\"not\\allowed@example.com
|
||||
151 |-stellyamburrr985@example.com
|
||||
152 |-Abc.123@example.com
|
||||
153 |-user+mailbox/department=shipping@example.com
|
||||
154 |-!#$%&'*+-/=?^_`.{|}~@example.com
|
||||
155 |-"Abc@def"@example.com
|
||||
156 |-"Fred\ Bloggs"@example.com
|
||||
157 |-"Joe.\\Blow"@example.com""".split("\n")
|
||||
135 |+[r"simple@example.com", r"very.common@example.com", r"FirstName.LastName@EasierReading.org", r"x@example.com", r"long.email-address-with-hyphens@and.subdomains.example.com", r"user.name+tag+sorting@example.com", r"name/surname@example.com", r"xample@s.example", r'" "@example.org', r'"john..doe"@example.org', r"mailhost!username@example.org", r'"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com', r"user%example.com@example.org", r"user-@example.org", r"I❤️CHOCOLATE@example.com", r'this\ still\"not\\allowed@example.com', r"stellyamburrr985@example.com", r"Abc.123@example.com", r"user+mailbox/department=shipping@example.com", r"!#$%&'*+-/=?^_`.{|}~@example.com", r'"Abc@def"@example.com', r'"Fred\ Bloggs"@example.com', r'"Joe.\\Blow"@example.com']
|
||||
158 136 |
|
||||
159 137 |
|
||||
160 138 | r"""first
|
||||
|
||||
SIM905.py:160:1: SIM905 [*] Consider using a list literal instead of `str.split`
|
||||
|
|
||||
160 | / r"""first
|
||||
161 | | 'no need' to escape
|
||||
162 | | "swap" quote style
|
||||
163 | | "use' ugly triple quotes""".split("\n")
|
||||
| |_______________________________________^ SIM905
|
||||
|
|
||||
= help: Replace with list literal
|
||||
|
||||
ℹ Safe fix
|
||||
157 157 | "Joe.\\Blow"@example.com""".split("\n")
|
||||
158 158 |
|
||||
159 159 |
|
||||
160 |-r"""first
|
||||
161 |-'no need' to escape
|
||||
162 |-"swap" quote style
|
||||
163 |-"use' ugly triple quotes""".split("\n")
|
||||
160 |+[r"first", r"'no need' to escape", r'"swap" quote style', r""""use' ugly triple quotes"""]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue