[Python-Dev] PEP 377 - allow __enter__() methods to skip the statement body

Nick Coghlan ncoghlan at gmail.com
Sun Mar 15 21:14:23 CET 2009


Michael Foord wrote:
> Brett Cannon wrote:
>> Without knowing what StatementSkipped is (just some singleton? If so
>> why not just used SkipStatement instance that was raised?)

It does get described in the full PEP - it is indeed just a singleton
like NotImplemented. That whole aspect of the PEP is something I'm not
entirely sure of at this stage - it may make more sense to just leave
the variables unbound. If a particular program cares to tell whether or
not the statement was skipped, that would still be easy enough to do:

  x = skipped = object()
  with cm() as x:
    do_stuff()

  if x is skipped:
    print "CM aborted with statement!"

Actually, now that I see how easy it is to do something equivalent for
yourself, I'm definitely going to drop the StatementSkipped assignment
part of the PEP in favour of just skipping over the variable assignment
part as well.

>> and
>> wondering if we are just going to continue to adding control flow
>> exceptions that directly inherit from BaseException or some
>> ControlFlowException base class, the basic idea seems fine by me.

Given how different the control flow exceptions are from each other, I
don't think it really makes sense to ever treat them as a cohesive
group. There's also the fact that StopIteration is a control flow
exception that doesn't inherit directly from BaseException.

> Note that using exceptions for control flow can  be bad for other
> implementations of Python. For example exceptions on the .NET framework
> are very expensive. (Although there are workarounds such as not really
> raising the exception - but they're ugly).

Is it that exceptions are expensive, or setting up a try/except block is
expensive? The reason the SkipStatement idea is tenable at all (even in
CPython) is that try/except is fairly cheap when no exception is raised.

(In this specific case, my initial patch does slow things down a bit,
since one side effect of the extra try/except block is to disallow a
couple of stack based optimisations that are used in the current CPython
implementation of the with statement)

> Isn't it better practise for exceptions to be used for exceptional
> circumstances rather than for control flow?

This *is* an exceptional circumstance: a typical __enter__ method will
just return or raise some other exception. I suppose you could use some
kind of dedicated thread-local state instead of an exception to indicate
that the underlying generator didn't yield, but a new control flow
exception seemed like the most straightforward option.

I'm somewhat intrigued by Glyph's idea though - if I can figure out a
way to make it practical, it does offer very some interesting
possibilities (and would, in effect, bring reusable embedded code blocks
to Python...).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------


More information about the Python-Dev mailing list