Add support for pycodestyle E101 (#2038)
Rule described here: https://www.flake8rules.com/rules/E101.html I tried to follow contributing guidelines closely, I've never worked with Rust before. Stumbled across Ruff a few days ago and would like to use it in our project, but we use a bunch of flake8 rules that are not yet implemented in ruff, so I decided to give it a go.
This commit is contained in:
@@ -596,6 +596,7 @@ For more, see [pycodestyle](https://pypi.org/project/pycodestyle/2.9.1/) on PyPI
|
||||
#### Error (E)
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| E101 | mixed-spaces-and-tabs | Indentation contains mixed spaces and tabs | |
|
||||
| E401 | multiple-imports-on-one-line | Multiple imports on one line | |
|
||||
| E402 | module-import-not-at-top-of-file | Module level import not at top of file | |
|
||||
| E501 | line-too-long | Line too long ({length} > {limit} characters) | |
|
||||
|
||||
19
resources/test/fixtures/pycodestyle/E101.py
vendored
Normal file
19
resources/test/fixtures/pycodestyle/E101.py
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
def func_all_spaces():
|
||||
# No error
|
||||
print("spaces")
|
||||
|
||||
def func_tabs():
|
||||
# No error
|
||||
print("tabs")
|
||||
|
||||
def func_mixed_start_with_tab():
|
||||
# E101
|
||||
print("mixed starts with tab")
|
||||
|
||||
def func_mixed_start_with_space():
|
||||
# E101
|
||||
print("mixed starts with space")
|
||||
|
||||
def xyz():
|
||||
# E101
|
||||
print("xyz");
|
||||
@@ -1311,6 +1311,9 @@
|
||||
"DTZ011",
|
||||
"DTZ012",
|
||||
"E",
|
||||
"E1",
|
||||
"E10",
|
||||
"E101",
|
||||
"E4",
|
||||
"E40",
|
||||
"E401",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::rules::pycodestyle::rules::{
|
||||
doc_line_too_long, line_too_long, no_newline_at_end_of_file,
|
||||
doc_line_too_long, line_too_long, mixed_spaces_and_tabs, no_newline_at_end_of_file,
|
||||
};
|
||||
use crate::rules::pygrep_hooks::rules::{blanket_noqa, blanket_type_ignore};
|
||||
use crate::rules::pyupgrade::rules::unnecessary_coding_comment;
|
||||
@@ -25,6 +25,7 @@ pub fn check_lines(
|
||||
let enforce_unnecessary_coding_comment = settings
|
||||
.rules
|
||||
.enabled(&Rule::PEP3120UnnecessaryCodingComment);
|
||||
let enforce_mixed_spaces_and_tabs = settings.rules.enabled(&Rule::MixedSpacesAndTabs);
|
||||
|
||||
let mut commented_lines_iter = commented_lines.iter().peekable();
|
||||
let mut doc_lines_iter = doc_lines.iter().peekable();
|
||||
@@ -72,6 +73,12 @@ pub fn check_lines(
|
||||
}
|
||||
}
|
||||
|
||||
if enforce_mixed_spaces_and_tabs {
|
||||
if let Some(diagnostic) = mixed_spaces_and_tabs(index, line) {
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
if enforce_line_too_long {
|
||||
if let Some(diagnostic) = line_too_long(index, line, settings) {
|
||||
diagnostics.push(diagnostic);
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::{rules, violations};
|
||||
|
||||
ruff_macros::define_rule_mapping!(
|
||||
// pycodestyle errors
|
||||
E101 => violations::MixedSpacesAndTabs,
|
||||
E401 => violations::MultipleImportsOnOneLine,
|
||||
E402 => violations::ModuleImportNotAtTopOfFile,
|
||||
E501 => violations::LineTooLong,
|
||||
@@ -556,7 +557,8 @@ impl Rule {
|
||||
| Rule::DocLineTooLong
|
||||
| Rule::PEP3120UnnecessaryCodingComment
|
||||
| Rule::BlanketTypeIgnore
|
||||
| Rule::BlanketNOQA => &LintSource::Lines,
|
||||
| Rule::BlanketNOQA
|
||||
| Rule::MixedSpacesAndTabs => &LintSource::Lines,
|
||||
Rule::AmbiguousUnicodeCharacterComment
|
||||
| Rule::AmbiguousUnicodeCharacterDocstring
|
||||
| Rule::AmbiguousUnicodeCharacterString
|
||||
|
||||
@@ -36,6 +36,7 @@ mod tests {
|
||||
#[test_case(Rule::NoNewLineAtEndOfFile, Path::new("W292_4.py"))]
|
||||
#[test_case(Rule::InvalidEscapeSequence, Path::new("W605_0.py"))]
|
||||
#[test_case(Rule::InvalidEscapeSequence, Path::new("W605_1.py"))]
|
||||
#[test_case(Rule::MixedSpacesAndTabs, Path::new("E101.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
|
||||
@@ -78,6 +78,23 @@ pub fn line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<D
|
||||
}
|
||||
}
|
||||
|
||||
/// E101
|
||||
pub fn mixed_spaces_and_tabs(lineno: usize, line: &str) -> Option<Diagnostic> {
|
||||
let indent = leading_space(line);
|
||||
|
||||
if indent.contains(' ') && indent.contains('\t') {
|
||||
Some(Diagnostic::new(
|
||||
violations::MixedSpacesAndTabs,
|
||||
Range::new(
|
||||
Location::new(lineno + 1, 0),
|
||||
Location::new(lineno + 1, indent.chars().count()),
|
||||
),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// W505
|
||||
pub fn doc_line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<Diagnostic> {
|
||||
let Some(limit) = settings.pycodestyle.max_doc_length else {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
source: src/rules/pycodestyle/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
MixedSpacesAndTabs: ~
|
||||
location:
|
||||
row: 11
|
||||
column: 0
|
||||
end_location:
|
||||
row: 11
|
||||
column: 3
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MixedSpacesAndTabs: ~
|
||||
location:
|
||||
row: 15
|
||||
column: 0
|
||||
end_location:
|
||||
row: 15
|
||||
column: 11
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MixedSpacesAndTabs: ~
|
||||
location:
|
||||
row: 19
|
||||
column: 0
|
||||
end_location:
|
||||
row: 19
|
||||
column: 4
|
||||
fix: ~
|
||||
parent: ~
|
||||
|
||||
@@ -48,6 +48,16 @@ impl Violation for LineTooLong {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct MixedSpacesAndTabs;
|
||||
);
|
||||
impl Violation for MixedSpacesAndTabs {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Indentation contains mixed spaces and tabs")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum EqCmpop {
|
||||
Eq,
|
||||
|
||||
Reference in New Issue
Block a user