mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-29 11:07:45 +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);
|
assert_messages!(snapshot, diagnostics);
|
||||||
Ok(())
|
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 ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::registry::Rule;
|
||||||
|
|
||||||
use super::super::settings::Quote;
|
use super::super::settings::Quote;
|
||||||
|
|
||||||
|
|
@ -334,6 +335,11 @@ fn strings(checker: &mut Checker, sequence: &[TextRange]) {
|
||||||
|
|
||||||
for (range, trivia) in sequence.iter().zip(trivia) {
|
for (range, trivia) in sequence.iter().zip(trivia) {
|
||||||
if trivia.is_multiline {
|
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 our string is or contains a known good string, ignore it.
|
||||||
if trivia
|
if trivia
|
||||||
.raw_text
|
.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.
|
// If we're not using the preferred type, only allow use to avoid escapes.
|
||||||
&& !relax_quote
|
&& !relax_quote
|
||||||
{
|
{
|
||||||
|
// If inline strings aren't enforced, ignore it.
|
||||||
|
if !checker.enabled(Rule::BadQuotesInlineString) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if trivia.has_empty_text()
|
if trivia.has_empty_text()
|
||||||
&& text_ends_at_quote(locator, *range, quotes_settings.inline_quotes)
|
&& 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() {
|
if checker.semantic().in_docstring() {
|
||||||
|
if checker.enabled(Rule::BadQuotesDocstring) {
|
||||||
for range in ranges {
|
for range in ranges {
|
||||||
docstring(checker, range);
|
docstring(checker, range);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if checker.any_enabled(&[Rule::BadQuotesInlineString, Rule::BadQuotesMultilineString]) {
|
||||||
strings(checker, &ranges);
|
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