[Python-Dev] PEP 340: Else clause for block statements

Guido van Rossum gvanrossum at gmail.com
Mon May 2 02:44:16 CEST 2005


[Nick Coghlan]
> As yet, I don't have a particularly firm opinion on whether or not block
> statements should support an 'else:' clause. And there are obviously a great
> many other questions to be answered about how block statements might work that
> are more important than this one.
> 
> Still, I've been tinkering with some ideas for how to approach this, and thought
> I'd write them up for everyone else's consideration.
> 
> Option 0:
>     No else clause allowed. Figured I should mention this, since it is Guido's
> last reported inclination, and my total lack of use cases for the other options
> below suggests this is the best idea for an initial implementation.

The more I think about it the more this makes the most sense because
it is the easiest to understand.

> Option 1: mimic try, for, while semantics
>     An 'else' clause on a block statement behaves like the else clause on for
> and while loops, and on try/except statements - the clause is executed only if
> the managed suite completes 'normally' (i.e. it is not terminated early due to
> an exception, a break statement or a return statement)

You'd have to define this very carefully. Because break is implemented
by passing StopIteration to the __next__ or __exit__ method (depending
on which alternative API we end up picking), and StopIteration is also
how these methods signal that the loop is over, it's a little tricky.
Assuming we go with __exit__ to pass an exception to the
iterator/generator, we could define that the else clause is executed
when the __next__ method raises StopIteration -- this would imply
exhaustion of the iterator from natural causes. This has the advantage
of matching the behavior of a for loop.

> Option 2: mimic if semantics
>    An 'else' clause on a block statement behaves vaguely like the else clause on
> an if statement - the clause is executed only if the first suite is never
> entered, but no exception occurs (i.e. StopIteration is raised by the first call
> to next).

Strange because it's different from the behavior of a for loop, and
the block-statement doesn't feel like an if-statement at all. But I
could actually imagine a use case: when acquiring a lock with a
time-out, the else-clause could be executed when the acquisition times
out.

  block locking(myLock, timeout=30):
      ...code executed with lock held...
  else:
      ...code executed if lock not acquired...

But I'm not convinced that this shouldn't be handled with a try/except
around it all; the use case doesn't appear all that common, and it
scares me that when the lock isn't aquired, this happens entirely
silently when there is no else-clause.

> Option 3: iterator-controlled semantics
>    The iterator is given the ability to control whether or not the else clause
> is executed (e.g. via an attribute of StopIteration), probably using option 1
> above as the default behaviour.

A slightly cleaner version would be to have a separate subclass of
StopIteration for this purpose. But I see serious problems with
explaining when the else-clause is executed, because it's too dynamic.
It does solve one problem with option 2 though: if there's no
else-clause, and ElseIteration is raised, that could become an error
rather than being ignored silently.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list