mirror of https://github.com/astral-sh/ruff
Generate verbatim nodes
This commit is contained in:
parent
7329bf459c
commit
00b3663b2d
|
|
@ -2287,6 +2287,7 @@ dependencies = [
|
|||
"ruff_python_literal",
|
||||
"ruff_python_parser",
|
||||
"ruff_source_file",
|
||||
"ruff_text_size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ impl<'a> Checker<'a> {
|
|||
self.f_string_quote_style().unwrap_or(self.stylist.quote()),
|
||||
self.stylist.line_ending(),
|
||||
)
|
||||
.with_locator(self.locator)
|
||||
}
|
||||
|
||||
/// Returns the appropriate quoting for f-string by reversing the one used outside of
|
||||
|
|
|
|||
|
|
@ -360,20 +360,6 @@ S608.py:48:12: S608 Possible SQL injection vector through string-based query con
|
|||
54 | def query38():
|
||||
|
|
||||
|
||||
S608.py:55:12: S608 Possible SQL injection vector through string-based query construction
|
||||
|
|
||||
54 | def query38():
|
||||
55 | return """
|
||||
| ____________^
|
||||
56 | | SELECT *
|
||||
57 | | FROM TABLE
|
||||
58 | | WHERE var =
|
||||
59 | | """ + var
|
||||
| |_____________^ S608
|
||||
60 |
|
||||
61 | def query39():
|
||||
|
|
||||
|
||||
S608.py:62:12: S608 Possible SQL injection vector through string-based query construction
|
||||
|
|
||||
61 | def query39():
|
||||
|
|
|
|||
|
|
@ -79,14 +79,15 @@ B006_B008.py:77:31: B006 [*] Do not use mutable data structures for argument def
|
|||
75 75 |
|
||||
76 76 |
|
||||
77 |-def multiline_arg_wrong(value={
|
||||
78 |-
|
||||
79 |-}):
|
||||
77 |+def multiline_arg_wrong(value=None):
|
||||
78 |+ if value is None:
|
||||
79 |+ value = {}
|
||||
80 80 | ...
|
||||
81 81 |
|
||||
82 82 | def single_line_func_wrong(value = {}): ...
|
||||
79 |+ value = {
|
||||
78 80 |
|
||||
79 |-}):
|
||||
81 |+ }
|
||||
80 82 | ...
|
||||
81 83 |
|
||||
82 84 | def single_line_func_wrong(value = {}): ...
|
||||
|
||||
B006_B008.py:82:36: B006 Do not use mutable data structures for argument defaults
|
||||
|
|
||||
|
|
@ -486,10 +487,12 @@ B006_B008.py:302:52: B006 [*] Do not use mutable data structures for argument de
|
|||
302 |+def single_line_func_wrong(value: dict[str, str] = None):
|
||||
305 303 | """Docstring"""
|
||||
304 |+ if value is None:
|
||||
305 |+ value = {}
|
||||
306 306 |
|
||||
307 307 |
|
||||
308 308 | def single_line_func_wrong(value: dict[str, str] = {}) \
|
||||
305 |+ value = {
|
||||
306 |+ # This is a comment
|
||||
307 |+ }
|
||||
306 308 |
|
||||
307 309 |
|
||||
308 310 | def single_line_func_wrong(value: dict[str, str] = {}) \
|
||||
|
||||
B006_B008.py:308:52: B006 Do not use mutable data structures for argument defaults
|
||||
|
|
||||
|
|
|
|||
|
|
@ -195,7 +195,10 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
});
|
||||
let bool_op = node;
|
||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
||||
checker.generator().expr(&bool_op),
|
||||
checker
|
||||
.generator()
|
||||
.with_locator(checker.locator())
|
||||
.expr(&bool_op),
|
||||
expr.range(),
|
||||
)));
|
||||
checker.diagnostics.push(diagnostic);
|
||||
|
|
|
|||
|
|
@ -382,7 +382,9 @@ PYI016.py:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]`
|
|||
46 46 | # Shouldn't emit if in new parent type
|
||||
47 47 | field16: int | dict[int, str] # OK
|
||||
|
||||
PYI016.py:57:5: PYI016 Duplicate union member `set[int]`
|
||||
PYI016.py:57:5: PYI016 Duplicate union member `set[
|
||||
int # bar
|
||||
]`
|
||||
|
|
||||
55 | int # foo
|
||||
56 | ],
|
||||
|
|
@ -393,7 +395,9 @@ PYI016.py:57:5: PYI016 Duplicate union member `set[int]`
|
|||
| |_____^ PYI016
|
||||
60 | ] # Error, newline and comment will not be emitted in message
|
||||
|
|
||||
= help: Remove duplicate union member `set[int]`
|
||||
= help: Remove duplicate union member `set[
|
||||
int # bar
|
||||
]`
|
||||
|
||||
PYI016.py:63:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -382,7 +382,9 @@ PYI016.pyi:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]`
|
|||
46 46 | # Shouldn't emit if in new parent type
|
||||
47 47 | field16: int | dict[int, str] # OK
|
||||
|
||||
PYI016.pyi:57:5: PYI016 Duplicate union member `set[int]`
|
||||
PYI016.pyi:57:5: PYI016 Duplicate union member `set[
|
||||
int # bar
|
||||
]`
|
||||
|
|
||||
55 | int # foo
|
||||
56 | ],
|
||||
|
|
@ -393,7 +395,9 @@ PYI016.pyi:57:5: PYI016 Duplicate union member `set[int]`
|
|||
| |_____^ PYI016
|
||||
60 | ] # Error, newline and comment will not be emitted in message
|
||||
|
|
||||
= help: Remove duplicate union member `set[int]`
|
||||
= help: Remove duplicate union member `set[
|
||||
int # bar
|
||||
]`
|
||||
|
||||
PYI016.pyi:63:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ PT009.py:73:9: PT009 [*] Use a regular `assert` instead of unittest-style `asser
|
|||
71 71 |
|
||||
72 72 | def test_assert_regex(self):
|
||||
73 |- self.assertRegex("abc", r"def") # Error
|
||||
73 |+ assert re.search("def", "abc") # Error
|
||||
73 |+ assert re.search(r"def", "abc") # Error
|
||||
74 74 |
|
||||
75 75 | def test_assert_not_regex(self):
|
||||
76 76 | self.assertNotRegex("abc", r"abc") # Error
|
||||
|
|
@ -518,7 +518,7 @@ PT009.py:76:9: PT009 [*] Use a regular `assert` instead of unittest-style `asser
|
|||
74 74 |
|
||||
75 75 | def test_assert_not_regex(self):
|
||||
76 |- self.assertNotRegex("abc", r"abc") # Error
|
||||
76 |+ assert not re.search("abc", "abc") # Error
|
||||
76 |+ assert not re.search(r"abc", "abc") # Error
|
||||
77 77 |
|
||||
78 78 | def test_assert_regexp_matches(self):
|
||||
79 79 | self.assertRegexpMatches("abc", r"def") # Error
|
||||
|
|
@ -538,7 +538,7 @@ PT009.py:79:9: PT009 [*] Use a regular `assert` instead of unittest-style `asser
|
|||
77 77 |
|
||||
78 78 | def test_assert_regexp_matches(self):
|
||||
79 |- self.assertRegexpMatches("abc", r"def") # Error
|
||||
79 |+ assert re.search("def", "abc") # Error
|
||||
79 |+ assert re.search(r"def", "abc") # Error
|
||||
80 80 |
|
||||
81 81 | def test_assert_not_regexp_matches(self):
|
||||
82 82 | self.assertNotRegex("abc", r"abc") # Error
|
||||
|
|
@ -558,7 +558,7 @@ PT009.py:82:9: PT009 [*] Use a regular `assert` instead of unittest-style `asser
|
|||
80 80 |
|
||||
81 81 | def test_assert_not_regexp_matches(self):
|
||||
82 |- self.assertNotRegex("abc", r"abc") # Error
|
||||
82 |+ assert not re.search("abc", "abc") # Error
|
||||
82 |+ assert not re.search(r"abc", "abc") # Error
|
||||
83 83 |
|
||||
84 84 | def test_fail_if(self):
|
||||
85 85 | self.failIf("abc") # Error
|
||||
|
|
@ -658,6 +658,7 @@ PT009.py:98:2: PT009 [*] Use a regular `assert` instead of unittest-style `asser
|
|||
98 |-(self.assertTrue(
|
||||
99 |- "piAx_piAy_beta[r][x][y] = {17}".format(
|
||||
100 |- self.model.piAx_piAy_beta[r][x][y])))
|
||||
98 |+assert "piAx_piAy_beta[r][x][y] = {17}".format(self.model.piAx_piAy_beta[r][x][y])
|
||||
98 |+assert "piAx_piAy_beta[r][x][y] = {17}".format(
|
||||
99 |+ self.model.piAx_piAy_beta[r][x][y])
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ SIM222.py:85:6: SIM222 [*] Use `True` instead of `... or True`
|
|||
87 87 | a or (1,) or True or (2,) # SIM222
|
||||
88 88 |
|
||||
|
||||
SIM222.py:87:6: SIM222 [*] Use `(1,)` instead of `(1,) or ...`
|
||||
SIM222.py:87:6: SIM222 [*] Use `((1,))` instead of `((1,)) or ...`
|
||||
|
|
||||
85 | a or tuple(()) or True # SIM222
|
||||
86 |
|
||||
|
|
@ -543,14 +543,14 @@ SIM222.py:87:6: SIM222 [*] Use `(1,)` instead of `(1,) or ...`
|
|||
88 |
|
||||
89 | a or tuple((1,)) or True or tuple((2,)) # SIM222
|
||||
|
|
||||
= help: Replace with `(1,)`
|
||||
= help: Replace with `((1,))`
|
||||
|
||||
ℹ Unsafe fix
|
||||
84 84 |
|
||||
85 85 | a or tuple(()) or True # SIM222
|
||||
86 86 |
|
||||
87 |-a or (1,) or True or (2,) # SIM222
|
||||
87 |+a or (1,) # SIM222
|
||||
87 |+a or ((1,)) # SIM222
|
||||
88 88 |
|
||||
89 89 | a or tuple((1,)) or True or tuple((2,)) # SIM222
|
||||
90 90 |
|
||||
|
|
@ -1006,39 +1006,39 @@ SIM222.py:153:11: SIM222 [*] Use `[1]` instead of `[1] or ...`
|
|||
155 155 |
|
||||
156 156 | # Regression test for: https://github.com/astral-sh/ruff/issues/7099
|
||||
|
||||
SIM222.py:157:30: SIM222 [*] Use `(int, int, int)` instead of `(int, int, int) or ...`
|
||||
SIM222.py:157:30: SIM222 [*] Use `((int, int, int))` instead of `((int, int, int)) or ...`
|
||||
|
|
||||
156 | # Regression test for: https://github.com/astral-sh/ruff/issues/7099
|
||||
157 | def secondToTime(s0: int) -> (int, int, int) or str:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ SIM222
|
||||
158 | m, s = divmod(s0, 60)
|
||||
|
|
||||
= help: Replace with `(int, int, int)`
|
||||
= help: Replace with `((int, int, int))`
|
||||
|
||||
ℹ Unsafe fix
|
||||
154 154 | pass
|
||||
155 155 |
|
||||
156 156 | # Regression test for: https://github.com/astral-sh/ruff/issues/7099
|
||||
157 |-def secondToTime(s0: int) -> (int, int, int) or str:
|
||||
157 |+def secondToTime(s0: int) -> (int, int, int):
|
||||
157 |+def secondToTime(s0: int) -> ((int, int, int)):
|
||||
158 158 | m, s = divmod(s0, 60)
|
||||
159 159 |
|
||||
160 160 |
|
||||
|
||||
SIM222.py:161:31: SIM222 [*] Use `(int, int, int)` instead of `(int, int, int) or ...`
|
||||
SIM222.py:161:31: SIM222 [*] Use `((int, int, int))` instead of `((int, int, int)) or ...`
|
||||
|
|
||||
161 | def secondToTime(s0: int) -> ((int, int, int) or str):
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ SIM222
|
||||
162 | m, s = divmod(s0, 60)
|
||||
|
|
||||
= help: Replace with `(int, int, int)`
|
||||
= help: Replace with `((int, int, int))`
|
||||
|
||||
ℹ Unsafe fix
|
||||
158 158 | m, s = divmod(s0, 60)
|
||||
159 159 |
|
||||
160 160 |
|
||||
161 |-def secondToTime(s0: int) -> ((int, int, int) or str):
|
||||
161 |+def secondToTime(s0: int) -> ((int, int, int)):
|
||||
161 |+def secondToTime(s0: int) -> (((int, int, int))):
|
||||
162 162 | m, s = divmod(s0, 60)
|
||||
163 163 |
|
||||
164 164 |
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ magic_value_comparison.py:59:22: PLR2004 Magic value used in comparison, conside
|
|||
60 | pass
|
||||
|
|
||||
|
||||
magic_value_comparison.py:65:21: PLR2004 Magic value used in comparison, consider replacing 3.141592653589793 with a constant variable
|
||||
magic_value_comparison.py:65:21: PLR2004 Magic value used in comparison, consider replacing 3.141592653589793238 with a constant variable
|
||||
|
|
||||
63 | pi_estimation = 3.14
|
||||
64 |
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ ruff_python_ast = { path = "../ruff_python_ast" }
|
|||
ruff_python_literal = { path = "../ruff_python_literal" }
|
||||
ruff_python_parser = { path = "../ruff_python_parser" }
|
||||
ruff_source_file = { path = "../ruff_source_file" }
|
||||
ruff_text_size = { path = "../ruff_text_size" }
|
||||
|
||||
once_cell = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ use ruff_python_ast::{
|
|||
};
|
||||
use ruff_python_ast::{ParameterWithDefault, TypeParams};
|
||||
use ruff_python_literal::escape::{AsciiEscape, Escape, UnicodeEscape};
|
||||
use ruff_source_file::LineEnding;
|
||||
use ruff_source_file::{LineEnding, Locator};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use super::stylist::{Indentation, Quote, Stylist};
|
||||
|
||||
|
|
@ -61,6 +62,11 @@ mod precedence {
|
|||
pub(crate) const MAX: u8 = 63;
|
||||
}
|
||||
|
||||
pub struct Verbatim<'a> {
|
||||
locator: &'a Locator<'a>,
|
||||
nodes: Vec<TextRange>,
|
||||
}
|
||||
|
||||
pub struct Generator<'a> {
|
||||
/// The indentation style to use.
|
||||
indent: &'a Indentation,
|
||||
|
|
@ -72,6 +78,7 @@ pub struct Generator<'a> {
|
|||
indent_depth: usize,
|
||||
num_newlines: usize,
|
||||
initial: bool,
|
||||
locator: Option<&'a Locator<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Stylist<'a>> for Generator<'a> {
|
||||
|
|
@ -84,6 +91,7 @@ impl<'a> From<&'a Stylist<'a>> for Generator<'a> {
|
|||
indent_depth: 0,
|
||||
num_newlines: 0,
|
||||
initial: true,
|
||||
locator: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,6 +108,15 @@ impl<'a> Generator<'a> {
|
|||
indent_depth: 0,
|
||||
num_newlines: 0,
|
||||
initial: true,
|
||||
locator: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_locator(self, locator: &'a Locator<'a>) -> Self {
|
||||
Self {
|
||||
locator: Some(locator),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -796,6 +813,14 @@ impl<'a> Generator<'a> {
|
|||
ret
|
||||
}};
|
||||
}
|
||||
|
||||
if let Some(locator) = &self.locator {
|
||||
if !ast.range().is_empty() {
|
||||
self.p(locator.slice(ast));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
match ast {
|
||||
Expr::BoolOp(ast::ExprBoolOp {
|
||||
op,
|
||||
|
|
|
|||
Loading…
Reference in New Issue