Skip to content

Detect empty conditional statements #13929

@gpauloski

Description

@gpauloski

Problem

Code deletion rules in ruff can sometimes leave unnecessary conditional blocks. Consider this common conditional import logic.

import sys

if sys.version_info >= (3, 11):
    from typing import Self
else:
    from typing_extensions import Self

If the file is refactored such that Self is no longer used, ruff check --fix will remove the unused imports leaving an empty if-else statement:

import sys

if sys.version_info >= (3, 11):
    pass
else:
    pass

This kind of statement is useless and could easily be overlooked when introduced by auto-formatting.

Related

This problem was originally raised in #9472, but I'm opening this issue to discuss the scope of a new rule in more detail.

There are a couple related rules that don't quite cover this problem:

  • RUF034 detects useless if-else expressions, but not statements (e.g, foo = x if y else x).
  • TCH005 can only detect empty TYPE_CHECKING blocks.

Proposal

A new empty-if-statement rule that detects if/if-else/if-elif-else statements where all arms are empty. This can have an autofix, but it would be an unsafe autofix since the test in the conditional could have a side-effect even if the body is empty.

As @MichaReiser brought up in #9472, there are some questions about scope:

  • Should an empty else in a for/try statement be detected?
  • What about an empty elif between a non-empty if and else?
  • Potential nuance with typing stubs.

If we are unsure about the first two, they could be ignored for now and revisited in a followup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ruleImplementing or modifying a lint rule

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions