Skip to content

Commit

Permalink
Update PLE2510, PLE2512-2515 to check in f-strings (#7387)
Browse files Browse the repository at this point in the history
## Summary

This PR updates `PLE2510`, `PLE2512-2515` to check in f-strings.

> ### Reference:
> * `PLE2510`: Invalid unescaped character backspace, use "\b" instead
> * `PLE2512`: Invalid unescaped character SUB, use "\x1A" instead
> * `PLE2513`: Invalid unescaped character ESC, use "\x1B" instead
> * `PLE2514`: Invalid unescaped character NUL, use "\0" instead
> * `PLE2515`: Invalid unescaped character zero-width-space, use
"\u200B" instead

## Test Plan

Add test cases for f-strings.
  • Loading branch information
dhruvmanila authored Sep 16, 2023
1 parent dd2178f commit e53db6c
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 80 deletions.
Binary file modified crates/ruff/resources/test/fixtures/pylint/invalid_characters.py
Binary file not shown.
4 changes: 1 addition & 3 deletions crates/ruff/src/checkers/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ pub(crate) fn check_tokens(
Rule::InvalidCharacterZeroWidthSpace,
]) {
for (tok, range) in tokens.iter().flatten() {
if tok.is_string() {
pylint::rules::invalid_string_characters(&mut diagnostics, *range, locator);
}
pylint::rules::invalid_string_characters(&mut diagnostics, tok, *range, locator);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use ruff_diagnostics::AlwaysAutofixableViolation;
use ruff_diagnostics::Edit;
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_parser::Tok;
use ruff_source_file::Locator;

/// ## What it does
Expand Down Expand Up @@ -173,10 +174,15 @@ impl AlwaysAutofixableViolation for InvalidCharacterZeroWidthSpace {
/// PLE2510, PLE2512, PLE2513, PLE2514, PLE2515
pub(crate) fn invalid_string_characters(
diagnostics: &mut Vec<Diagnostic>,
tok: &Tok,
range: TextRange,
locator: &Locator,
) {
let text = locator.slice(range);
let text = match tok {
Tok::String { .. } => locator.slice(range),
Tok::FStringMiddle { value, .. } => value.as_str(),
_ => return,
};

for (column, match_) in text.match_indices(&['\x08', '\x1A', '\x1B', '\0', '\u{200b}']) {
let c = match_.chars().next().unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ invalid_characters.py:15:6: PLE2510 [*] Invalid unescaped character backspace, u
14 | #foo = 'hi'
15 | b = ''
| PLE2510
16 |
17 | b_ok = '\\b'
16 | b = f''
|
= help: Replace with escape sequence

Expand All @@ -18,8 +17,45 @@ invalid_characters.py:15:6: PLE2510 [*] Invalid unescaped character backspace, u
14 14 | #foo = 'hi'
15 |-b = ''
15 |+b = '\b'
16 16 |
17 17 | b_ok = '\\b'
18 18 |
16 16 | b = f''
17 17 |
18 18 | b_ok = '\\b'

invalid_characters.py:16:7: PLE2510 [*] Invalid unescaped character backspace, use "\b" instead
|
14 | #foo = 'hi'
15 | b = ''
16 | b = f''
| PLE2510
17 |
18 | b_ok = '\\b'
|
= help: Replace with escape sequence

Fix
13 13 | # (Pylint, "C3002") => Rule::UnnecessaryDirectLambdaCall,
14 14 | #foo = 'hi'
15 15 | b = ''
16 |-b = f''
16 |+b = f'\b'
17 17 |
18 18 | b_ok = '\\b'
19 19 | b_ok = f'\\b'

invalid_characters.py:55:21: PLE2510 [*] Invalid unescaped character backspace, use "\b" instead
|
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
54 |
55 | nested_fstrings = f'{f'{f''}'}'
| PLE2510
|
= help: Replace with escape sequence

Fix
52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
54 54 |
55 |-nested_fstrings = f'{f'{f''}'}'
55 |+nested_fstrings = f'\b{f'{f''}'}'


Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
---
source: crates/ruff/src/rules/pylint/mod.rs
---
invalid_characters.py:21:12: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead
invalid_characters.py:24:12: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead
|
19 | cr_ok = '\\r'
20 |
21 | sub = 'sub '
22 | cr_ok = f'\\r'
23 |
24 | sub = 'sub '
| PLE2512
22 |
23 | sub_ok = '\x1a'
25 | sub = f'sub '
|
= help: Replace with escape sequence

Fix
18 18 |
19 19 | cr_ok = '\\r'
20 20 |
21 |-sub = 'sub '
21 |+sub = 'sub \x1A'
22 22 |
23 23 | sub_ok = '\x1a'
24 24 |
21 21 | cr_ok = '\\r'
22 22 | cr_ok = f'\\r'
23 23 |
24 |-sub = 'sub '
24 |+sub = 'sub \x1A'
25 25 | sub = f'sub '
26 26 |
27 27 | sub_ok = '\x1a'

invalid_characters.py:25:13: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead
|
24 | sub = 'sub '
25 | sub = f'sub '
| PLE2512
26 |
27 | sub_ok = '\x1a'
|
= help: Replace with escape sequence

Fix
22 22 | cr_ok = f'\\r'
23 23 |
24 24 | sub = 'sub '
25 |-sub = f'sub '
25 |+sub = f'sub \x1A'
26 26 |
27 27 | sub_ok = '\x1a'
28 28 | sub_ok = f'\x1a'

invalid_characters.py:55:25: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead
|
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
54 |
55 | nested_fstrings = f'{f'{f''}'}'
| PLE2512
|
= help: Replace with escape sequence

Fix
52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
54 54 |
55 |-nested_fstrings = f'{f'{f''}'}'
55 |+nested_fstrings = f'{f'\x1A{f''}'}'


Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
---
source: crates/ruff/src/rules/pylint/mod.rs
---
invalid_characters.py:25:16: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead
invalid_characters.py:30:16: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead
|
23 | sub_ok = '\x1a'
24 |
25 | esc = 'esc esc '
28 | sub_ok = f'\x1a'
29 |
30 | esc = 'esc esc '
| PLE2513
26 |
27 | esc_ok = '\x1b'
31 | esc = f'esc esc '
|
= help: Replace with escape sequence

Fix
22 22 |
23 23 | sub_ok = '\x1a'
24 24 |
25 |-esc = 'esc esc '
25 |+esc = 'esc esc \x1B'
26 26 |
27 27 | esc_ok = '\x1b'
28 28 |
27 27 | sub_ok = '\x1a'
28 28 | sub_ok = f'\x1a'
29 29 |
30 |-esc = 'esc esc '
30 |+esc = 'esc esc \x1B'
31 31 | esc = f'esc esc '
32 32 |
33 33 | esc_ok = '\x1b'

invalid_characters.py:31:17: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead
|
30 | esc = 'esc esc '
31 | esc = f'esc esc '
| PLE2513
32 |
33 | esc_ok = '\x1b'
|
= help: Replace with escape sequence

Fix
28 28 | sub_ok = f'\x1a'
29 29 |
30 30 | esc = 'esc esc '
31 |-esc = f'esc esc '
31 |+esc = f'esc esc \x1B'
32 32 |
33 33 | esc_ok = '\x1b'
34 34 | esc_ok = f'\x1b'

invalid_characters.py:55:29: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead
|
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
54 |
55 | nested_fstrings = f'{f'{f''}'}'
| PLE2513
|
= help: Replace with escape sequence

Fix
52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​"
54 54 |
55 |-nested_fstrings = f'{f'{f''}'}'
55 |+nested_fstrings = f'{f'{f'\x1B'}'}'


Binary file not shown.
Loading

0 comments on commit e53db6c

Please sign in to comment.