[code-quality] Spurious useless-else-on-loop warning
Skip Montanaro
skip at pobox.com
Tue Sep 17 20:56:19 CEST 2013
I have a function which uses for ... else, with an early return.
Here's a cut down version of it:
"""..."""
def func(c, dt, ct):
for cl, op in zip(c.events[0::2], c.events[1::2]):
delta = cl.event_datetime - dt
if delta > ct:
return dt + ct
else:
dt = op.event_datetime
ct -= delta
else:
return dt
Pylint (1.0.0) complains:
early_exit.py:11: [W0120(useless-else-on-loop), func] Else clause on
loop without a break statement
I thought to myself, "self, a return should be treated like a break,"
and set out to fix this problem. I found the suspect code in
checkers/base.py:
def _loop_exits_early(loop):
"""Returns true if a loop has a break statement in its body."""
loop_nodes = (astroid.For, astroid.While)
# Loop over body explicitly to avoid matching break statements
# in orelse.
for child in loop.body:
if isinstance(child, loop_nodes):
continue
for _ in child.nodes_of_class(astroid.Break, skip_klass=loop_nodes):
return True
return False
Looking to see where a test case would go, I found
test/input/func_useless_else_on_loop.py, with this test case:
def test_return_for():
"""else + return is accetable."""
for i in range(10):
if i % 2:
return i
else:
print 'math is broken'
Given that _loop_exits_early doesn't check for early returns, how does
test_return_for (and test_return_while, not shown) pass when the test
suite is run?
I think these two lines belong in _loop_exits_early:
for _ in child.nodes_of_class(astroid.Return, skip_klass=loop_nodes):
return True
assuming there is no way to spell that with just a single call to
child.nodes_of_class().
(I tried updating my repo, but can't remember my bitbucket password,
otherwise I would have checked to see if this problem has already been
solved. My apologies if it has.)
Skip
More information about the code-quality
mailing list