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

[ruff] Needless else clause (RUF047) #15051

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

InSyncWithFoo
Copy link
Contributor

Summary

Partially addresses #13929.

Test Plan

cargo nextest run and cargo insta test.

Copy link
Contributor

github-actions bot commented Dec 19, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+6 -0 violations, +0 -0 fixes in 2 projects; 53 projects unchanged)

apache/airflow (+4 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

+ providers/src/airflow/providers/google/cloud/operators/bigquery.py:1629:9: RUF047 [*] Empty `else` clause
+ providers/tests/fab/auth_manager/api_endpoints/test_asset_endpoint.py:38:5: RUF047 [*] Empty `else` clause
+ providers/tests/fab/auth_manager/api_endpoints/test_dag_run_endpoint.py:44:5: RUF047 [*] Empty `else` clause
+ tests/models/test_taskinstance.py:2356:17: RUF047 [*] Empty `else` clause

lnbits/lnbits (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ lnbits/core/crud.py:791:5: RUF047 [*] Empty `else` clause
+ lnbits/core/crud.py:800:5: RUF047 [*] Empty `else` clause

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
RUF047 6 6 0 0 0

@MichaReiser MichaReiser added rule Implementing or modifying a lint rule preview Related to preview mode features labels Dec 19, 2024
@MichaReiser MichaReiser self-assigned this Dec 19, 2024
Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

I refactored your rule to remove some duplication and simplified it to only detect single pass or ... statements. PIE790 detects bodies containing both a ... and a pass statement.

I further extended the test cases and there's one case where we fail to detect a useless else because of the comment and one case where we marked the else as useless when we should not. We have to take the indent of the comments into consideration. See

fn handle_own_line_comment_between_branches<'a>(
and
fn handle_own_line_comment_after_branch<'a>(

Maybe we can come up with a simpler heuristic for this specific case?

/// Checks for `else` clauses that only contains `pass` and `...` statements.
///
/// ## Why is this bad?
/// Such a clause is unnecessary.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Such a clause is unnecessary.
/// Such an else clause does nothing and can be removed.

}

fn fix_title(&self) -> String {
"Remove clause".to_string()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Remove clause".to_string()
"Remove the `else` clause".to_string()

Comment on lines +419 to +422
#[test_case(Rule::NeedlessElse, Path::new("RUF047_if.py"))]
#[test_case(Rule::NeedlessElse, Path::new("RUF047_for.py"))]
#[test_case(Rule::NeedlessElse, Path::new("RUF047_while.py"))]
#[test_case(Rule::NeedlessElse, Path::new("RUF047_try.py"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The needless-else rule has no mode.is_preview checks. We can add it to the normal rules test, which simplifies promoting them to stable.

Comment on lines +64 to +73
RUF047_if.py:41:1: RUF047 [*] Empty `else` clause
|
39 | if of_course():
40 | this()
41 | / else:
42 | | ...
| |_______^ RUF047
43 | # comment
|
= help: Remove clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not suggest this fix because the comment belongs to the else clause

Comment on lines +21 to +26
if this_second_comment():
belongs() # to
# `else`
else:
pass

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should detect that this else branch is useless because the comment belongs to the if block

@InSyncWithFoo
Copy link
Contributor Author

InSyncWithFoo commented Dec 19, 2024

@MichaReiser If indentation is to be taken into consideration, should this be reported or not?

if test:
    _4_spaces()
  # 2 spaces
else:
    ...

What about this?

if test:
	_1_tab()  # These two lines would align if tabs are displayed as 1 character wide.
 # 1 space
else:
	...

# Same question, but for 2, 3, 4 spaces?

@MichaReiser
Copy link
Member

We should implement it so that it's consistent with the formatter. Your examples get formatted to

if test:
    _1_tab()  # These two lines would align if tabs are displayed as 1 character wide.
    # 1 space
else:
    ...

# Same question, but for 2, 3, 4 spaces?

if test:
    _4_spaces()
# 2 spaces
else:
    ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
preview Related to preview mode features rule Implementing or modifying a lint rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants