Skip to content

Commit

Permalink
Extend unnecessary-pass (PIE790) to trigger on all unnecessary `p…
Browse files Browse the repository at this point in the history
…ass` statements (#7697)

## Summary

Extend `unnecessary-pass` (`PIE790`) to trigger on all unnecessary
`pass` statements by checking for `pass` statements in any class or
function body with more than one statement.

Closes #7600.

## Test Plan

`cargo test`
  • Loading branch information
tjkuson committed Sep 29, 2023
1 parent 5989745 commit 3347524
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 80 deletions.
11 changes: 11 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE790.py
Expand Up @@ -123,3 +123,14 @@ class Error(Exception):

def foo() -> None:
pass


def foo():
print("foo")
pass


def foo():
"""A docstring."""
print("foo")
pass
4 changes: 2 additions & 2 deletions crates/ruff_linter/src/rules/flake8_pie/rules/mod.rs
@@ -1,17 +1,17 @@
pub(crate) use duplicate_class_field_definition::*;
pub(crate) use multiple_starts_ends_with::*;
pub(crate) use no_unnecessary_pass::*;
pub(crate) use non_unique_enums::*;
pub(crate) use reimplemented_list_builtin::*;
pub(crate) use unnecessary_dict_kwargs::*;
pub(crate) use unnecessary_pass::*;
pub(crate) use unnecessary_range_start::*;
pub(crate) use unnecessary_spread::*;

mod duplicate_class_field_definition;
mod multiple_starts_ends_with;
mod no_unnecessary_pass;
mod non_unique_enums;
mod reimplemented_list_builtin;
mod unnecessary_dict_kwargs;
mod unnecessary_pass;
mod unnecessary_range_start;
mod unnecessary_spread;

This file was deleted.

77 changes: 77 additions & 0 deletions crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_pass.rs
@@ -0,0 +1,77 @@
use ruff_python_ast::Stmt;

use ruff_diagnostics::AlwaysFixableViolation;
use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::whitespace::trailing_comment_start_offset;
use ruff_text_size::Ranged;

use crate::checkers::ast::Checker;
use crate::fix;
use crate::registry::AsRule;

/// ## What it does
/// Checks for unnecessary `pass` statements in functions, classes, and other
/// blocks.
///
/// ## Why is this bad?
/// In Python, the `pass` statement serves as a placeholder, allowing for
/// syntactically correct empty code blocks. The primary purpose of the `pass`
/// statement is to avoid syntax errors in situations where a statement is
/// syntactically required, but no code needs to be executed.
///
/// If a `pass` statement is present in a code block that includes at least
/// one other statement (even, e.g., a docstring), it is unnecessary and should
/// be removed.
///
/// ## Example
/// ```python
/// def func():
/// """Placeholder docstring."""
/// pass
/// ```
///
/// Use instead:
/// ```python
/// def func():
/// """Placeholder docstring."""
/// ```
///
/// ## References
/// - [Python documentation: The `pass` statement](https://docs.python.org/3/reference/simple_stmts.html#the-pass-statement)
#[violation]
pub struct UnnecessaryPass;

impl AlwaysFixableViolation for UnnecessaryPass {
#[derive_message_formats]
fn message(&self) -> String {
format!("Unnecessary `pass` statement")
}

fn fix_title(&self) -> String {
"Remove unnecessary `pass`".to_string()
}
}

/// PIE790
pub(crate) fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) {
if body.len() < 2 {
return;
}

body.iter()
.filter(|stmt| stmt.is_pass_stmt())
.for_each(|stmt| {
let mut diagnostic = Diagnostic::new(UnnecessaryPass, stmt.range());
if checker.patch(diagnostic.kind.rule()) {
let edit =
if let Some(index) = trailing_comment_start_offset(stmt, checker.locator()) {
Edit::range_deletion(stmt.range().add_end(index))
} else {
fix::edits::delete_stmt(stmt, None, checker.locator(), checker.indexer())
};
diagnostic.set_fix(Fix::automatic(edit));
}
checker.diagnostics.push(diagnostic);
});
}
Expand Up @@ -317,4 +317,37 @@ PIE790.py:101:5: PIE790 [*] Unnecessary `pass` statement
103 103 |
104 104 | class Foo:

PIE790.py:130:5: PIE790 [*] Unnecessary `pass` statement
|
128 | def foo():
129 | print("foo")
130 | pass
| ^^^^ PIE790
|
= help: Remove unnecessary `pass`

Fix
127 127 |
128 128 | def foo():
129 129 | print("foo")
130 |- pass
131 130 |
132 131 |
133 132 | def foo():

PIE790.py:136:5: PIE790 [*] Unnecessary `pass` statement
|
134 | """A docstring."""
135 | print("foo")
136 | pass
| ^^^^ PIE790
|
= help: Remove unnecessary `pass`

Fix
133 133 | def foo():
134 134 | """A docstring."""
135 135 | print("foo")
136 |- pass


0 comments on commit 3347524

Please sign in to comment.