for -- else: what was the motivation?
Axy
axy at declassed.art
Mon Oct 10 13:08:39 EDT 2022
> 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)
More information about the Python-list
mailing list