Skip to content
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

[pycodestyle] Add blank line(s) rules (E301, E302, E303, E304, E305, E306) #9266

Merged
merged 128 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 120 commits
Commits
Show all changes
128 commits
Select commit Hold shift + click to select a range
32ec9e7
Add V1 version.
hoel-bagard Nov 9, 2023
624c7a5
Keep track of previous streak of blank lines to fix 301.
hoel-bagard Nov 10, 2023
cd02e11
Fix 302.
hoel-bagard Nov 12, 2023
f9a19ef
Fix 305.
hoel-bagard Nov 12, 2023
a10bea3
Fix 306.
hoel-bagard Nov 12, 2023
f57b614
Fix 303 regression.
hoel-bagard Nov 12, 2023
42c6f12
Add snapshots.
hoel-bagard Nov 12, 2023
2283019
Update nursery rules list
hoel-bagard Nov 12, 2023
06618c2
Add a non-error test and its corresponding fix.
hoel-bagard Nov 12, 2023
09b6ba1
Add a TODO comment.
hoel-bagard Nov 12, 2023
1bdd181
Update snapshots following 06618c2.
hoel-bagard Nov 12, 2023
2a7b4cb
Clippy fixes.
hoel-bagard Nov 12, 2023
aa7b6e6
Store line.is_comment_only()'s result in a variable. Use config more.
hoel-bagard Nov 16, 2023
8d3744d
Do not ignore first logical line when it comes to tracked vars.
hoel-bagard Nov 16, 2023
d670100
Merge branch 'astral-sh:main' into add_blank_lines_E30_V2
hoel-bagard Nov 16, 2023
bd282ec
Remove unnecessary check.
hoel-bagard Nov 16, 2023
2ef4d02
Update snapshots (Fix -> Safe fix)
hoel-bagard Nov 16, 2023
36d2547
Fix first logical line issue.
hoel-bagard Nov 16, 2023
0f61011
Fix false positive caused by a class's docstring.
hoel-bagard Nov 16, 2023
0e9ca4e
Only trigger E302 on non-indented classes/functions.
hoel-bagard Nov 16, 2023
3f6f207
Fix decorator linked false positive.
hoel-bagard Nov 16, 2023
b667c5c
Fix E301 false positive.
hoel-bagard Nov 17, 2023
0bf4c45
Fix decorator + async false positive.
hoel-bagard Nov 18, 2023
7de1e05
Fix E302 error message.
hoel-bagard Nov 18, 2023
0c1450a
Improve E302's fix interaction with comments.
hoel-bagard Nov 18, 2023
7b9b277
Fix E301 regression and improve E301 fix.
hoel-bagard Nov 18, 2023
1d7b235
Fix E302 fix's interaction with comments.
hoel-bagard Nov 18, 2023
73e5ba9
Clippy fix.
hoel-bagard Nov 18, 2023
c1a7a7c
Fix docstring + comment leading to false positive.
hoel-bagard Nov 19, 2023
b484ca4
Fix E305 false positive for indented classes/defs
hoel-bagard Nov 19, 2023
6d0fbf2
Make rules independent.
hoel-bagard Nov 19, 2023
f7b2f89
Fix typo.
hoel-bagard Nov 19, 2023
5365830
Rule simplification.
hoel-bagard Nov 19, 2023
bafddf9
Fix E306 false negative when using async or decorator.
hoel-bagard Nov 19, 2023
ea9d9c8
Simplify/fix E301's condition.
hoel-bagard Nov 19, 2023
4d2f7b5
Make if condition more readable.
hoel-bagard Nov 19, 2023
0867011
Simplify E301's if condition.
hoel-bagard Nov 19, 2023
9f2d339
Remove unnecessary clone.
hoel-bagard Nov 19, 2023
46b0c46
Merge branch 'astral-sh:main' into add_blank_lines_E30_V2
hoel-bagard Nov 19, 2023
3eb5c62
Modify E303 to use top-levelness instead of class/def.
hoel-bagard Nov 21, 2023
9b15d8c
Remove unnecessary clone derive.
hoel-bagard Nov 21, 2023
fd65c70
Update E306
hoel-bagard Nov 24, 2023
883818b
is_first_logical_line -> is_not_first_logical_line to be able to deri…
hoel-bagard Nov 28, 2023
29f0e6b
Remove BlankLinesConfig struct and use module level constants instead.
hoel-bagard Nov 28, 2023
0b6bfdf
Use an enum to keep track of class and fn status.
hoel-bagard Nov 28, 2023
304115a
Remove for loop, clippy fixes.
hoel-bagard Nov 28, 2023
083f4f5
Remove unnecessary Option from is_docstring.
hoel-bagard Nov 28, 2023
60311c3
Use an enum to keep track of what the line is following.
hoel-bagard Nov 28, 2023
dc2fe49
Update crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/b…
hoel-bagard Nov 28, 2023
727a17b
BlankLinesTrackingVars -> BlankLinesChecker
hoel-bagard Nov 28, 2023
0635407
WIP
hoel-bagard Dec 14, 2023
199257d
Started building LogicalLine replacement.
hoel-bagard Dec 16, 2023
2002a6b
Mostly finished renaming variable.
hoel-bagard Dec 16, 2023
92da66c
Remove blank line counting in logical lines.
hoel-bagard Dec 16, 2023
7099fca
Bug fixes.
hoel-bagard Dec 16, 2023
5a59006
Clippy fixes.
hoel-bagard Dec 16, 2023
f1205a1
Add comment.
hoel-bagard Dec 16, 2023
6927937
Move the blank_lines outside the logical_lines module.
hoel-bagard Dec 24, 2023
fa55850
Merge with upstream.
hoel-bagard Dec 24, 2023
94fe6ef
Move check to the tokens' file.
hoel-bagard Dec 24, 2023
f2d4957
Remove unused import.
hoel-bagard Dec 24, 2023
c9cf6b6
Fix rule placement in the registry.
hoel-bagard Dec 24, 2023
6f3aa5c
Ignore clippy warnings.
hoel-bagard Dec 24, 2023
55a918d
Split if conditions into multiple ifs.
hoel-bagard Dec 24, 2023
9f2268c
Fix 2 false positives linked to indentation.
hoel-bagard Dec 29, 2023
66f4dd4
Fix false positive caused by bad async handling.
hoel-bagard Dec 29, 2023
3aac64d
Add test fixture.
hoel-bagard Dec 29, 2023
b7727c5
Remove async as a top level token.
hoel-bagard Dec 29, 2023
ba7d8d7
Fix is_top_level_token docstring.
hoel-bagard Jan 10, 2024
0bcdf7d
Use usize for preceding_blank_characters.
hoel-bagard Jan 10, 2024
ede587a
Use TokenKind instead of Tok
hoel-bagard Jan 10, 2024
f330584
Use == comparison instead of matches! where possible
hoel-bagard Jan 10, 2024
4437cc9
Use TokenKind::is_trivia to reduce nesting.
hoel-bagard Jan 10, 2024
3647ec5
Remove dead if branch.
hoel-bagard Jan 10, 2024
26417b9
Update crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs
hoel-bagard Jan 10, 2024
8bc8960
Give violations' u32 field a name and make it private.
hoel-bagard Jan 10, 2024
22cd072
Simplify and explain is_docstring flag detection.
hoel-bagard Jan 10, 2024
3f3ccfa
Replace unwrap by expect.
hoel-bagard Jan 10, 2024
12d80ed
check_content -> check_lines
hoel-bagard Jan 10, 2024
86c473c
Move BlankLinesChecker struct declaration closer to its implementatio…
hoel-bagard Jan 10, 2024
c347761
Remove unnecessary clip allow.
hoel-bagard Jan 10, 2024
820480f
Passing TokenKind by value.
hoel-bagard Jan 10, 2024
3df1f1b
Remove unnecessary clip allow (too many arguments).
hoel-bagard Jan 10, 2024
cce4d00
Update crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs
hoel-bagard Jan 10, 2024
92fca24
Update crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs
hoel-bagard Jan 10, 2024
8985a39
Revert "Update crates/ruff_linter/src/rules/pycodestyle/rules/blank_l…
hoel-bagard Jan 10, 2024
3941e8f
Fix visual indent.
hoel-bagard Jan 10, 2024
1831879
Fix visual indent.
hoel-bagard Jan 10, 2024
52589e4
Revert unrelated variable name change.
hoel-bagard Jan 10, 2024
4f2c318
Add tests with indentation made of 2 spaces, tabs and mixed spaces an…
hoel-bagard Jan 10, 2024
94c9bab
Do not use an hard coded indent size.
hoel-bagard Jan 10, 2024
da11f02
Fix missing else branch
hoel-bagard Jan 10, 2024
531ce0e
Remove outdated Async check.
hoel-bagard Jan 10, 2024
cc81cc3
Remove unecessary if.
hoel-bagard Jan 10, 2024
bdfb1e3
Move follow docstring if block outside of comment only if block.
hoel-bagard Jan 10, 2024
894bc21
Remove unecessary comment check condition.
hoel-bagard Jan 10, 2024
0f659b9
Only store the last token's end instead of full range.
hoel-bagard Jan 10, 2024
0d36444
Rename indent_level to indent_length
hoel-bagard Jan 10, 2024
6054707
refactor: make current_blank_lines and current_blank_characters into …
hoel-bagard Jan 13, 2024
4c54d05
docs: add docstring to explain the difference between blank_lines and…
hoel-bagard Jan 13, 2024
c07ccdf
docs: expand on the previous_blank_lines comment.
hoel-bagard Jan 13, 2024
5e342ac
refactor: previous_blank_lines -> preceding_blank_lines
hoel-bagard Jan 13, 2024
280ba51
Merge remote-tracking branch 'origin/main' into blank_lines_non_logical
MichaReiser Jan 15, 2024
273a711
Fix clippy errors.
hoel-bagard Jan 15, 2024
2fb48bc
Introduce `LogicalLineKind`
MichaReiser Jan 15, 2024
cafe5ff
Remove the need for `line_start`
MichaReiser Jan 15, 2024
e739a44
Add a few new tests, remove unnecessary `as_str` and `to_string` calls
MichaReiser Jan 15, 2024
f9a0d2d
Merge branch 'blank_lines_non_logical' of github.com:hoel-bagard/ruff…
MichaReiser Jan 15, 2024
b244f22
Reorder tests.
hoel-bagard Jan 19, 2024
f814990
Add comments to the text fixture.
hoel-bagard Jan 19, 2024
2c08381
Use BlankLines enum and keep track of the blank lines range.
hoel-bagard Jan 20, 2024
fddc740
Remove line.blank_lines_len and use BlankLines enum instead.
hoel-bagard Jan 20, 2024
c2f6a0c
Add E304 fixture.
hoel-bagard Jan 20, 2024
7ee8946
Improve E304 fix.
hoel-bagard Jan 20, 2024
24bf585
Match pycodestyle error message for E305.
hoel-bagard Jan 21, 2024
71d9057
docs: add comment about preceding_blank_lines vs blank_lines.
hoel-bagard Jan 22, 2024
181fdee
Merge branch 'main' into blank_lines_non_logical
MichaReiser Feb 5, 2024
8392f20
Move status update logic into its own function, mark rules as preview
MichaReiser Feb 5, 2024
0ddcca4
Introduce `blank_lines.range` method
MichaReiser Feb 5, 2024
de559d8
Use `universal_newlines` for decorator fix
MichaReiser Feb 6, 2024
db137d9
Small code simpliciations
MichaReiser Feb 6, 2024
85302d5
add wrongly indented comment test
hoel-bagard Feb 6, 2024
3d5cc84
fix E301 docstring.
hoel-bagard Feb 6, 2024
0596eda
fix E302 docstring.
hoel-bagard Feb 6, 2024
d188e20
Fix E301's fix message
hoel-bagard Feb 6, 2024
e89c20f
Fix E304's docstring.
hoel-bagard Feb 6, 2024
a28f916
Fix error message capitalization.
hoel-bagard Feb 6, 2024
aea3493
Remove unnecessary state variables
MichaReiser Feb 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
792 changes: 792 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pycodestyle/E30.py

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions crates/ruff_linter/src/checkers/logical_lines.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::line_width::IndentWidth;
use ruff_diagnostics::Diagnostic;
use ruff_python_codegen::Stylist;
use ruff_python_parser::lexer::LexResult;
Expand All @@ -15,11 +16,11 @@ use crate::rules::pycodestyle::rules::logical_lines::{
use crate::settings::LinterSettings;

/// Return the amount of indentation, expanding tabs to the next multiple of the settings' tab size.
fn expand_indent(line: &str, settings: &LinterSettings) -> usize {
pub(crate) fn expand_indent(line: &str, indent_width: IndentWidth) -> usize {
let line = line.trim_end_matches(['\n', '\r']);

let mut indent = 0;
let tab_size = settings.tab_size.as_usize();
let tab_size = indent_width.as_usize();
for c in line.bytes() {
match c {
b'\t' => indent = (indent / tab_size) * tab_size + tab_size,
Expand Down Expand Up @@ -85,7 +86,7 @@ pub(crate) fn check_logical_lines(
TextRange::new(locator.line_start(first_token.start()), first_token.start())
};

let indent_level = expand_indent(locator.slice(range), settings);
let indent_level = expand_indent(locator.slice(range), settings.tab_size);

let indent_size = 4;

Expand Down
22 changes: 22 additions & 0 deletions crates/ruff_linter/src/checkers/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::Path;

use ruff_notebook::CellOffsets;
use ruff_python_ast::PySourceType;
use ruff_python_codegen::Stylist;
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::Tok;

Expand All @@ -14,24 +15,45 @@ use ruff_source_file::Locator;
use crate::directives::TodoComment;
use crate::lex::docstring_detection::StateMachine;
use crate::registry::{AsRule, Rule};
use crate::rules::pycodestyle::rules::BlankLinesChecker;
use crate::rules::ruff::rules::Context;
use crate::rules::{
eradicate, flake8_commas, flake8_executable, flake8_fixme, flake8_implicit_str_concat,
flake8_pyi, flake8_quotes, flake8_todos, pycodestyle, pygrep_hooks, pylint, pyupgrade, ruff,
};
use crate::settings::LinterSettings;

#[allow(clippy::too_many_arguments)]
pub(crate) fn check_tokens(
tokens: &[LexResult],
path: &Path,
locator: &Locator,
indexer: &Indexer,
stylist: &Stylist,
settings: &LinterSettings,
source_type: PySourceType,
cell_offsets: Option<&CellOffsets>,
) -> Vec<Diagnostic> {
let mut diagnostics: Vec<Diagnostic> = vec![];

if settings.rules.any_enabled(&[
Rule::BlankLineBetweenMethods,
Rule::BlankLinesTopLevel,
Rule::TooManyBlankLines,
Rule::BlankLineAfterDecorator,
Rule::BlankLinesAfterFunctionOrClass,
Rule::BlankLinesBeforeNestedDefinition,
]) {
let mut blank_lines_checker = BlankLinesChecker::default();
blank_lines_checker.check_lines(
tokens,
locator,
stylist,
settings.tab_size,
&mut diagnostics,
);
}

if settings.rules.enabled(Rule::BlanketNOQA) {
pygrep_hooks::rules::blanket_noqa(&mut diagnostics, indexer, locator);
}
Expand Down
6 changes: 6 additions & 0 deletions crates/ruff_linter/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Pycodestyle, "E274") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabBeforeKeyword),
#[allow(deprecated)]
(Pycodestyle, "E275") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword),
(Pycodestyle, "E301") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLineBetweenMethods),
(Pycodestyle, "E302") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLinesTopLevel),
(Pycodestyle, "E303") => (RuleGroup::Preview, rules::pycodestyle::rules::TooManyBlankLines),
(Pycodestyle, "E304") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLineAfterDecorator),
(Pycodestyle, "E305") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLinesAfterFunctionOrClass),
(Pycodestyle, "E306") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLinesBeforeNestedDefinition),
(Pycodestyle, "E401") => (RuleGroup::Stable, rules::pycodestyle::rules::MultipleImportsOnOneLine),
(Pycodestyle, "E402") => (RuleGroup::Stable, rules::pycodestyle::rules::ModuleImportNotAtTopOfFile),
(Pycodestyle, "E501") => (RuleGroup::Stable, rules::pycodestyle::rules::LineTooLong),
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub fn check_path(
path,
locator,
indexer,
stylist,
settings,
source_type,
source_kind.as_ipy_notebook().map(Notebook::cell_offsets),
Expand Down
6 changes: 6 additions & 0 deletions crates/ruff_linter/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ impl Rule {
| Rule::BadQuotesMultilineString
| Rule::BlanketNOQA
| Rule::BlanketTypeIgnore
| Rule::BlankLineAfterDecorator
| Rule::BlankLineBetweenMethods
| Rule::BlankLinesAfterFunctionOrClass
| Rule::BlankLinesBeforeNestedDefinition
| Rule::BlankLinesTopLevel
| Rule::CommentedOutCode
| Rule::EmptyComment
| Rule::ExtraneousParentheses
Expand Down Expand Up @@ -296,6 +301,7 @@ impl Rule {
| Rule::ShebangNotFirstLine
| Rule::SingleLineImplicitStringConcatenation
| Rule::TabIndentation
| Rule::TooManyBlankLines
| Rule::TrailingCommaOnBareTuple
| Rule::TypeCommentInStub
| Rule::UselessSemicolon
Expand Down
7 changes: 7 additions & 0 deletions crates/ruff_linter/src/rules/pycodestyle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ mod tests {
Path::new("E25.py")
)]
#[test_case(Rule::MissingWhitespaceAroundParameterEquals, Path::new("E25.py"))]
#[test_case(Rule::BlankLineBetweenMethods, Path::new("E30.py"))]
#[test_case(Rule::BlankLinesTopLevel, Path::new("E30.py"))]
#[test_case(Rule::TooManyBlankLines, Path::new("E30.py"))]
#[test_case(Rule::BlankLineAfterDecorator, Path::new("E30.py"))]
#[test_case(Rule::BlankLinesAfterFunctionOrClass, Path::new("E30.py"))]
#[test_case(Rule::BlankLinesBeforeNestedDefinition, Path::new("E30.py"))]

fn logical(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
let diagnostics = test_path(
Expand Down
Loading
Loading