Generalize `elif-else-finally` to all compound statements - #23 by xitop has suggested a bigger change including finally
. However, the feedback revealed that finally
should ideally be left out.
So apologies for creating very similar thread, but I think clean new thread to get feedback on narrowed down idea is more productive and time saving for everyone.
1. Proposal
Add optional elif
clauses to statements that support else
, but elif
is not allowed. These are the following 3:
for
statement.
for target in iter:
...
elif condition: # 0 or more
...
else: # 0 or 1
...
while
statement
while condition0:
...
elif condition1: # 0 or more
...
else: # 0 or 1
...
try-except
statement
try:
...
except Exception: # 1 or more
...
elif condition: # 0 or more
...
else: # 0 or 1
...
finally: # 0 or 1
...
In essence, this would allow flattening out nested compound statements.
while condition0:
...
else:
if condition1:
...
becomes:
while condition0:
...
elif condition1:
...
And:
while condition0:
...
else:
if condition1:
...
else:
...
becomes:
while condition0:
...
elif condition1:
...
else:
...
The same is true for all 3 compound statements.
2. Use cases
Cases in CPython repo and few accompanying links:
for <target> <iter>:\n<indented-lines>else:\nif
- 81
1.1 multiprocessing/pool.py:534
1.2 zoneinfo/_zoneinfo.py:249
1.3 stat.py:167while <cond>:\n<indented-lines>else:\nif
- 2
2.1 textwrap.py:320
2.2 tkinter/dnd.py:156try:\n<indented-lines>else:\nif
- 10
3.1 uuid.py:430
3.2 socket.py:388
3.3 ssl.py:336
Cpython repo with site-packages from .venv.
try-else-if
- 407for-else-if
- 114while-else-if
- 28
Notes:
- These numbers contain little to no false positives.
- Non-trivial portion of cases is not captured. E.g. blank-lines are not allowed. (If I add conditional new line
re
search never finishes) - These numbers are fairly significant compared to code-usage searches I have done in the past.
Random concrete example: asyncio/unix_events.py:548
try:
data = os.read(self._fileno, self.max_size)
except (BlockingIOError, InterruptedError):
pass
except OSError as exc:
self._fatal_error(exc, 'Fatal read error on pipe transport')
else:
if data:
self._protocol.data_received(data)
Would become:
try:
data = os.read(self._fileno, self.max_size)
except (BlockingIOError, InterruptedError):
pass
except OSError as exc:
self._fatal_error(exc, 'Fatal read error on pipe transport')
elif data:
self._protocol.data_received(data)
The proposal is very simple in concept and implementation.
So could this be worth implementing?