for -- else: what was the motivation?
Weatherby,Gerard
gweatherby at uchc.edu
Mon Oct 10 14:25:19 EDT 2022
pylint, at least, provides a warning:
fe.py:4:0: W0120: Else clause on loop without a break statement (useless-else-on-loop)
sum = 0
for i in range(5):
sum += i
else:
print("Always executes")
print(sum)
From: Python-list <python-list-bounces+gweatherby=uchc.edu at python.org> on behalf of Axy via Python-list <python-list at python.org>
Date: Monday, October 10, 2022 at 1:10 PM
To: python-list at python.org <python-list at python.org>
Subject: Re: for -- else: what was the motivation?
*** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***
> On 10/10/2022 15:52, Weatherby,Gerard wrote:
>> I wonder if for/else could have been less confusing if it was
>> referred to
>> as for-break-else and if the else clause was only valid syntax if the
>> for
>> loop actually contained a break statement in the first place.
>
> Sounds reasonable. It would be something alike UnboundLocalError when
> a local variable referenced before assignment. If they won't remove
> "else" completely in far future, that checking really worths
> implementing now.
Actually, I think a warning would be sufficient, as in the following
quick prototype. If someone can implement this quickly in CPython, that
would be great (last time I hacked it, it was 2.4)
Axy.
import ast
tree = ast.parse('''
# sample code
a = 0
for i in 'asd':
a += i
while x:
pass
else:
print('wow')
break
print(i)
else:
print(0)
''', mode='exec')
def check_ast(node):
if isinstance(node, (ast.For, ast.AsyncFor, ast.While)):
if node.orelse and have_no_break(node.body):
print(f'Warning: the loop at line {node.lineno} has no
"break" statement,'
f' "else" clause at line {node.orelse[0].lineno}
won\'t run')
else:
for child in ast.iter_child_nodes(node):
check_ast(child)
def have_no_break(loop_body):
for node in loop_body:
if isinstance(node, (ast.For, ast.AsyncFor, ast.While)):
# nested loop
check_ast(node)
elif isinstance(node, ast.Break):
return False
elif isinstance(node, list):
for child in ast.iter_child_nodes(node):
if have_no_break(child) == False:
return False
return True
for node in tree.body:
check_ast(node)
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!mlK4jRkfDC_akw-fIqWaMVf707GQsiyvj_sRHTsFnuG4ak5mKWwSavtz4njlBNIu1H0VHrR9gyjuQpxGqZ1dacU1Xw$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!mlK4jRkfDC_akw-fIqWaMVf707GQsiyvj_sRHTsFnuG4ak5mKWwSavtz4njlBNIu1H0VHrR9gyjuQpxGqZ1dacU1Xw$>
More information about the Python-list
mailing list