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....@python.org> on behalf of Axy via Python-list <python-list@python.org> Date: Monday, October 10, 2022 at 1:10 PM To: python-list@python.org <python-list@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$> -- https://mail.python.org/mailman/listinfo/python-list