Skip to content

Forbid "fat" finally #3458

@efimov-mikhail

Description

@efimov-mikhail

Rule request

Allow finally block to have simple content only.
It can contain few lines of code, but it shouldn't contain untrivial logic, which can not be understand very quickly at code reading.

Thesis

Correct finally block:

  1. One-two statements.
  2. One if with elif and else w/o sub-blocks.

Wrong finally block:
One bloated with business logic and hard to read.

It's arguable when exactly the watershed should be located.
I propose something like this for correct finally:

  1. Up to 10 statements.
  2. Up to 2 levels of indentation (i.e. sub-blocks)
  3. Maybe up to 10 basic tokens in each statement.

Reasoning

IMO, finally block best suites for code snippets like this:

try:
    x = open_something()
    y = x.read_value()
    ...
except SomeError as e:
   ...
finally:
    close_something(x)

It's easy to read and understand what finally block stands for.
But code with big and difficult finally block smells.

My arguments are here:

  1. Code in finally block should basically do nothing other than some "cleaning" or "finishing" after try and provide only necessary things. If some code can be located after try-except-finally, it should be located there, and not in finally itself.
  2. There is an accepted PEP 765 (https://peps.python.org/pep-0765/) which disallow return/break/continue in finally block for 3.14+. Thus finally is already block with very special rules, we just want to make those rules to be more strict.
  3. Generated bytecode has two copies of finally block content on latest CPython versions. As a result, big finally block provide larger code objects.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions