[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