[Python-Dev] Exception chaining and generator finalisation

Nick Coghlan ncoghlan at gmail.com
Sun Aug 1 07:51:09 CEST 2010


On Sun, Aug 1, 2010 at 1:25 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Nick Coghlan wrote:
>
>> I don't see it as an implementation detail - it's part of the spec of
>> generator finalisation in PEP 342
>
> It doesn't seem like something you need to know in this
> situation, though. All it tells you is that the finalisation
> is happening because the generator is being closed rather
> than completing on its own.

That may be important though (e.g. if the generator hasn't been
written to correctly take into account the possibility of exceptions
being thrown in, then knowing the exception happened when
GeneratorExit in particular was thrown in rather than when next() was
called or a different exception was thrown in may matter for the
debugging process).

Basically, I disagree with your assumption that knowing GeneratorExit
was involved won't be significant in figuring why the generator threw
an exception at all, so I see this as providing useful exception
context information rather than being untidy noise. A toy example,
that isn't obviously broken at first glance, but in fact fails when
close() is called:

def toy_gen():
    try:
       yield 1
    except Exception as ex:
      exc = ex
    else:
      exc = None
    finally:
      if exc is not None: print(type(exc))

>>> g = toy_gen()
>>> next(g)
1
>>> g.throw(NameError)
<class 'NameError'>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> g = toy_gen()
>>> next(g)
1
>>> g.close()
Traceback (most recent call last):
  File "<stdin>", line 3, in toy_gen
GeneratorExit

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in toy_gen
UnboundLocalError: local variable 'exc' referenced before assignment

Without knowing GeneratorExit was thrown, the UnboundLocalError would
be rather confusing. Given GeneratorExit to work with though, it
shouldn't be hard for a developer to realise that "exc" won't be set
when a thrown exception inherits directly from BaseException rather
than from Exception.

Cheers,
Nick.

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


More information about the Python-Dev mailing list