mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-27 18:36:23 +00:00
Respect Q00* ignores in flake8-quotes rules (#10728)
## Summary We lost the per-rule ignores when these were migrated to the AST, so if _any_ `Q` rule is enabled, they're now all enabled. Closes https://github.com/astral-sh/ruff/issues/10724. ## Test Plan Ran: ```shell ruff check . --isolated --select Q --ignore Q000 ruff check . --isolated --select Q --ignore Q001 ruff check . --isolated --select Q --ignore Q002 ruff check . --isolated --select Q --ignore Q000,Q001 ruff check . --isolated --select Q --ignore Q000,Q002 ruff check . --isolated --select Q --ignore Q001,Q002 ``` ...against: ```python ''' bad docsting ''' a = 'single' b = ''' bad multi line ''' ```
This commit is contained in:
parent
d36f60999d
commit
7b48443624
6 changed files with 146 additions and 3 deletions
7
crates/ruff_linter/resources/test/fixtures/flake8_quotes/doubles_all.py
vendored
Normal file
7
crates/ruff_linter/resources/test/fixtures/flake8_quotes/doubles_all.py
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"""This is a docstring."""
|
||||
|
||||
this_is_an_inline_string = "double quote string"
|
||||
|
||||
this_is_a_multiline_string = """
|
||||
double quote string
|
||||
"""
|
||||
|
|
@ -195,4 +195,61 @@ mod tests {
|
|||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("doubles_all.py"))]
|
||||
fn only_inline(path: &Path) -> Result<()> {
|
||||
let snapshot = format!("only_inline_{}", path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_quotes").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_quotes: super::settings::Settings {
|
||||
inline_quotes: Quote::Single,
|
||||
multiline_quotes: Quote::Single,
|
||||
docstring_quotes: Quote::Single,
|
||||
avoid_escape: true,
|
||||
},
|
||||
..LinterSettings::for_rules(vec![Rule::BadQuotesInlineString])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("doubles_all.py"))]
|
||||
fn only_multiline(path: &Path) -> Result<()> {
|
||||
let snapshot = format!("only_multiline_{}", path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_quotes").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_quotes: super::settings::Settings {
|
||||
inline_quotes: Quote::Single,
|
||||
multiline_quotes: Quote::Single,
|
||||
docstring_quotes: Quote::Single,
|
||||
avoid_escape: true,
|
||||
},
|
||||
..LinterSettings::for_rules(vec![Rule::BadQuotesMultilineString])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("doubles_all.py"))]
|
||||
fn only_docstring(path: &Path) -> Result<()> {
|
||||
let snapshot = format!("only_docstring_{}", path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_quotes").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_quotes: super::settings::Settings {
|
||||
inline_quotes: Quote::Single,
|
||||
multiline_quotes: Quote::Single,
|
||||
docstring_quotes: Quote::Single,
|
||||
avoid_escape: true,
|
||||
},
|
||||
..LinterSettings::for_rules(vec![Rule::BadQuotesDocstring])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use ruff_source_file::Locator;
|
|||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Rule;
|
||||
|
||||
use super::super::settings::Quote;
|
||||
|
||||
|
|
@ -334,6 +335,11 @@ fn strings(checker: &mut Checker, sequence: &[TextRange]) {
|
|||
|
||||
for (range, trivia) in sequence.iter().zip(trivia) {
|
||||
if trivia.is_multiline {
|
||||
// If multiline strings aren't enforced, ignore it.
|
||||
if !checker.enabled(Rule::BadQuotesMultilineString) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If our string is or contains a known good string, ignore it.
|
||||
if trivia
|
||||
.raw_text
|
||||
|
|
@ -375,6 +381,11 @@ fn strings(checker: &mut Checker, sequence: &[TextRange]) {
|
|||
// If we're not using the preferred type, only allow use to avoid escapes.
|
||||
&& !relax_quote
|
||||
{
|
||||
// If inline strings aren't enforced, ignore it.
|
||||
if !checker.enabled(Rule::BadQuotesInlineString) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if trivia.has_empty_text()
|
||||
&& text_ends_at_quote(locator, *range, quotes_settings.inline_quotes)
|
||||
{
|
||||
|
|
@ -455,10 +466,14 @@ pub(crate) fn check_string_quotes(checker: &mut Checker, string_like: StringLike
|
|||
};
|
||||
|
||||
if checker.semantic().in_docstring() {
|
||||
for range in ranges {
|
||||
docstring(checker, range);
|
||||
if checker.enabled(Rule::BadQuotesDocstring) {
|
||||
for range in ranges {
|
||||
docstring(checker, range);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
strings(checker, &ranges);
|
||||
if checker.any_enabled(&[Rule::BadQuotesInlineString, Rule::BadQuotesMultilineString]) {
|
||||
strings(checker, &ranges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_quotes/mod.rs
|
||||
---
|
||||
doubles_all.py:1:1: Q002 [*] Double quote docstring found but single quotes preferred
|
||||
|
|
||||
1 | """This is a docstring."""
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Q002
|
||||
2 |
|
||||
3 | this_is_an_inline_string = "double quote string"
|
||||
|
|
||||
= help: Replace double quotes docstring with single quotes
|
||||
|
||||
ℹ Safe fix
|
||||
1 |-"""This is a docstring."""
|
||||
1 |+'''This is a docstring.'''
|
||||
2 2 |
|
||||
3 3 | this_is_an_inline_string = "double quote string"
|
||||
4 4 |
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_quotes/mod.rs
|
||||
---
|
||||
doubles_all.py:3:28: Q000 [*] Double quotes found but single quotes preferred
|
||||
|
|
||||
1 | """This is a docstring."""
|
||||
2 |
|
||||
3 | this_is_an_inline_string = "double quote string"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ Q000
|
||||
4 |
|
||||
5 | this_is_a_multiline_string = """
|
||||
|
|
||||
= help: Replace double quotes with single quotes
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | """This is a docstring."""
|
||||
2 2 |
|
||||
3 |-this_is_an_inline_string = "double quote string"
|
||||
3 |+this_is_an_inline_string = 'double quote string'
|
||||
4 4 |
|
||||
5 5 | this_is_a_multiline_string = """
|
||||
6 6 | double quote string
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_quotes/mod.rs
|
||||
---
|
||||
doubles_all.py:5:30: Q001 [*] Double quote multiline found but single quotes preferred
|
||||
|
|
||||
3 | this_is_an_inline_string = "double quote string"
|
||||
4 |
|
||||
5 | this_is_a_multiline_string = """
|
||||
| ______________________________^
|
||||
6 | | double quote string
|
||||
7 | | """
|
||||
| |___^ Q001
|
||||
|
|
||||
= help: Replace double multiline quotes with single quotes
|
||||
|
||||
ℹ Safe fix
|
||||
2 2 |
|
||||
3 3 | this_is_an_inline_string = "double quote string"
|
||||
4 4 |
|
||||
5 |-this_is_a_multiline_string = """
|
||||
5 |+this_is_a_multiline_string = '''
|
||||
6 6 | double quote string
|
||||
7 |-"""
|
||||
7 |+'''
|
||||
Loading…
Add table
Add a link
Reference in a new issue