Forbid "fat" finally
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:
- One-two statements.
- One
ifwithelifandelsew/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:
- Up to 10 statements.
- Up to 2 levels of indentation (i.e. sub-blocks)
- 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:
- Code in
finallyblock should basically do nothing other than some "cleaning" or "finishing" aftertryand provide only necessary things. If some code can be located aftertry-except-finally, it should be located there, and not infinallyitself. - There is an accepted PEP 765 (https://peps.python.org/pep-0765/) which disallow
return/break/continueinfinallyblock for 3.14+. Thusfinallyis already block with very special rules, we just want to make those rules to be more strict. - Generated bytecode has two copies of
finallyblock content on latest CPython versions. As a result, bigfinallyblock provide larger code objects.
I would put it like this: we need a rule that counts max lines in finally, by default it should be 2. Configuration should be also available.
I can work. I want to take up this issue.
How to deal with a function call with multiple arguments? Black will split it into multiple lines, which is ok for me. And there is no way to avoid that. Except using partial, but it's ugly. Even a function with one argument and a long name will use 3 lines of code. I suggest allowing one function call without a line number restriction. The number of arguments in a function already has its own rule.
It should not be reported. We should only count top-level statements. Not inner ones. Please, send a fix if this is the case.
It should not be reported. We should only count top-level statements. Not inner ones. Please, send a fix if this is the case.
Will be very complicated to fix. The code itself validates only number of lines. Error message, tests and error description focus only on this aspect. It should be removed and rewriten completly, as far as I inderstood. I suggest to use the same rules as in try..except block. It counts statements correctly and strict enogh.
Yes, please :)