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

Nick Coghlan ncoghlan at gmail.com
Sun Mar 15 21:40:00 CET 2009


Nick Coghlan wrote:
> Rough spec for the concept:
> 
> Implementing __enter__/__exit__ on a CM would work as per PEP 343.
> 
> Implementing __with__ instead would give the CM complete control over
> whether or not to execute the block.
> 
> The implementation of contextlib.GeneratorContextManager would then
> change so that instead of providing __enter__/__exit__ as it does now it
> would instead provide __with__ as follows:

Expansion in the previous message wasn't quite right since it didn't
give the executed block access to the result of __enter__().

Mark II:

  def __with__(self, exec_block):
    try:
      enter_result = self.gen.next()
    except StopIteration:
      pass
    else:
      try:
        exec_block(enter_result)
      except:
        exc_type, value, traceback = sys.exc_info()
        try:
          self.gen.throw(type, value, traceback)
          raise RuntimeError("generator didn't stop after throw()")
        except StopIteration, exc:
          # Suppress the exception *unless* it's the same exception that
          # was passed to throw().  This prevents a StopIteration
          # raised inside the "with" statement from being suppressed
          return exc is not value
        except:
          # only re-raise if it's *not* the exception that was
          # passed to throw(), because __exit__() must not raise
          # an exception unless __exit__() itself failed.  But throw()
          # has to raise the exception to signal propagation, so this
          # fixes the impedance mismatch between the throw() protocol
          # and the __exit__() protocol.
          if sys.exc_info()[1] is not value:
            raise
      else:
        try:
          self.gen.next()
        except StopIteration:
          return
        else:
          raise RuntimeError("generator didn't stop")


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


More information about the Python-Dev mailing list