2011/4/18 Stefan Behnel <stefan...@behnel.de>: > Vitja Makarov, 17.04.2011 17:57: >> >> 3. check_yield_in_exception() > > I added this because I found a failing pyregr test that uses it (testing the > @contextmanager decorator). > > >> Cython calls __Pyx_ExceptionReset when except block is done, so when >> yield is there no exception reset is called. >> >> I'm not sure how to fix this. > > I'm not completely sure either. > > >> import sys >> >> def foo(): >> """ >> >>> list(foo()) >> [<type 'exceptions.ValueError'>, None] >> """ >> try: >> raise ValueError >> except ValueError: >> yield sys.exc_info()[0] >> yield sys.exc_info()[0] # exc_info is lost here > > I think (!), the difference here is that CPython actually keeps the > exception in the generator frame. We don't have a frame, so we have to > emulate it using the closure class. I guess we'll have to store away the > exception into the closure when we yield while an exception is being > handled, and restore it afterwards. Note: this is not the exception that is > freshly *being* raised (the "_cur*" fields in the thread state), it's the > exception that *was* raised and is now being handled, i.e. the thread state > fields without the "_cur", that are reflected by sys.exc_info(). >
Interesting difference between py2 and py3: def foo(): try: raise ValueError except ValueError: yield raise list(foo()) File "xxx.py", line 7, in <module> list(foo()) File "xxx.py", line 6, in foo raise TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType It seems that exception info is completely lost (tried 2.6, 2.7) and seems to be fixed in python3. Btw exception info temps are already saved and restored between yields. -- vitja. _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel