-
Notifications
You must be signed in to change notification settings - Fork 882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pylint
] invalid-characters-*
#3552
Merged
Merged
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
b44af4c
[pylint] invalid-characters-*
r3m0t 6234107
Apply suggestions from code review
r3m0t 2027747
fixes
r3m0t c978974
Merge remote-tracking branch 'upstream/main' into chars-b
r3m0t f27e1f3
Tweak documentation
charliermarsh 28c9d9e
Merge branch 'main' into chars-b
charliermarsh File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
205 changes: 205 additions & 0 deletions
205
crates/ruff/src/rules/pylint/rules/invalid_string_characters.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
use rustpython_parser::ast::Location; | ||
|
||
use ruff_macros::{derive_message_formats, violation}; | ||
|
||
use ruff_diagnostics::AlwaysAutofixableViolation; | ||
use ruff_diagnostics::Fix; | ||
use ruff_diagnostics::{Diagnostic, DiagnosticKind}; | ||
use ruff_python_ast::source_code::Locator; | ||
use ruff_python_ast::types::Range; | ||
|
||
/// ## What it does | ||
/// Checks that strings don't have the control character BS | ||
/// | ||
/// ## Why is this bad? | ||
/// Control characters can display differently in different text editors and terminals. By using the \b sequence the string's | ||
/// value will be the same but it will be visible in all text editors. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// x = '' | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// x = '\b' | ||
/// ``` | ||
#[violation] | ||
pub struct InvalidCharacterBackspace; | ||
|
||
impl AlwaysAutofixableViolation for InvalidCharacterBackspace { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Invalid unescaped character backspace, use \"\\b\" instead") | ||
} | ||
|
||
fn autofix_title(&self) -> String { | ||
"Replace with escape sequence".to_string() | ||
} | ||
} | ||
|
||
/// ## What it does | ||
/// Checks that strings don't have the raw control character SUB | ||
/// | ||
/// ## Why is this bad? | ||
/// Control characters can display differently in different text editors and terminals. By using the \x1B sequence the string's | ||
/// value will be the same but it will be visible in all text editors. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// x = '' | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// x = '\x1A' | ||
/// ``` | ||
|
||
r3m0t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[violation] | ||
pub struct InvalidCharacterSub; | ||
|
||
impl AlwaysAutofixableViolation for InvalidCharacterSub { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Invalid unescaped character SUB, use \"\\x1A\" instead") | ||
} | ||
|
||
fn autofix_title(&self) -> String { | ||
"Replace with escape sequence".to_string() | ||
} | ||
} | ||
|
||
/// ## What it does | ||
/// Checks that strings don't have the raw control character ESC | ||
/// | ||
/// ## Why is this bad? | ||
/// Control characters can display differently in different text editors and terminals. By using the \x1B sequence the string's | ||
/// value will be the same but it will be visible in all text editors. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// x = '' | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// x = '\x1B' | ||
/// ``` | ||
|
||
r3m0t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[violation] | ||
pub struct InvalidCharacterEsc; | ||
|
||
impl AlwaysAutofixableViolation for InvalidCharacterEsc { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Invalid unescaped character ESC, use \"\\x1B\" instead") | ||
} | ||
|
||
fn autofix_title(&self) -> String { | ||
"Replace with escape sequence".to_string() | ||
} | ||
} | ||
|
||
/// ## What it does | ||
/// Checks that strings don't have the raw control character NUL (0 byte) | ||
/// | ||
/// ## Why is this bad? | ||
/// Control characters can display differently in different text editors and terminals. By using the \x1B sequence the string's | ||
/// value will be the same but it will be visible in all text editors. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// x = '' | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// x = '\0' | ||
/// ``` | ||
|
||
r3m0t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[violation] | ||
pub struct InvalidCharacterNul; | ||
|
||
impl AlwaysAutofixableViolation for InvalidCharacterNul { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Invalid unescaped character NUL, use \"\\0\" instead") | ||
} | ||
|
||
fn autofix_title(&self) -> String { | ||
"Replace with escape sequence".to_string() | ||
} | ||
} | ||
|
||
/// ## What it does | ||
/// Checks that strings don't have the zero width space character | ||
/// | ||
/// ## Why is this bad? | ||
/// This character can be invisible in some text editors and terminals. By using the \x1B sequence the string's | ||
/// value will be the same but it will be visible in all text editors. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// x = 'Dear Sir/Madam' | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// x = 'Dear Sir\u200B/\u200BMadam' # zero width space | ||
/// ``` | ||
|
||
r3m0t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[violation] | ||
pub struct InvalidCharacterZeroWidthSpace; | ||
|
||
impl AlwaysAutofixableViolation for InvalidCharacterZeroWidthSpace { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Invalid unescaped character zero-width-space, use \"\\u200B\" instead") | ||
} | ||
|
||
fn autofix_title(&self) -> String { | ||
"Replace with escape sequence".to_string() | ||
} | ||
} | ||
|
||
/// PLE2510, PLE2512, PLE2513, PLE2514, PLE2515 | ||
pub fn invalid_string_characters( | ||
locator: &Locator, | ||
start: Location, | ||
end: Location, | ||
autofix: bool, | ||
) -> Vec<Diagnostic> { | ||
let mut diagnostics = Vec::new(); | ||
let text = locator.slice(Range::new(start, end)); | ||
|
||
for (row_offset, line) in text.lines().enumerate() { | ||
r3m0t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for (col_offset, m) in line.match_indices(&['\x08', '\x1A', '\x1B', '\0', '\u{200b}']) { | ||
let col = if row_offset == 0 { | ||
start.column() + col_offset | ||
} else { | ||
col_offset | ||
}; | ||
let (replacement, rule): (&str, DiagnosticKind) = match m.chars().next().unwrap() { | ||
'\x08' => ("\\b", InvalidCharacterBackspace.into()), | ||
'\x1A' => ("\\x1A", InvalidCharacterSub.into()), | ||
'\x1B' => ("\\x1B", InvalidCharacterEsc.into()), | ||
'\0' => ("\\0", InvalidCharacterNul.into()), | ||
'\u{200b}' => ("\\u200b", InvalidCharacterZeroWidthSpace.into()), | ||
_ => unreachable!(), | ||
}; | ||
let location = Location::new(start.row() + row_offset, col); | ||
let end_location = Location::new(location.row(), location.column() + 1); | ||
let mut diagnostic = Diagnostic::new(rule, Range::new(location, end_location)); | ||
if autofix { | ||
diagnostic.amend(Fix::replacement( | ||
replacement.to_string(), | ||
location, | ||
end_location, | ||
)); | ||
} | ||
diagnostics.push(diagnostic); | ||
} | ||
} | ||
|
||
diagnostics | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Use
any_enabled
?