coroutine, throw, yield, call-stack and exception handling

Veek. M vek.m1234 at gmail.com
Tue Feb 9 06:55:56 EST 2016


Ian Kelly wrote:

> On Mon, Feb 8, 2016 at 2:17 AM, Veek. M <vek.m1234 at gmail.com> wrote:
>> ****************************
>> Exceptions can be raised inside a coroutine using the throw(
>>
>> Exceptions raised in this manner will originate at the currently
>> executing yield state-ment in the coroutine.A coroutine can elect to
>> catch exceptions and handle them as appropriate. It is not safe to
>> use throw() as an asynchronous signal to a coroutine—it should never
>> be invoked from a separate execution thread or in a signal handler.
>> ****************************
>>
>> What does Beazley mean by this: 'will originate at the currently
>> executing yield state-ment in the coroutine'
>>
>> If he's throw'ing an exception surely it originates at the throw:
>>
>> def mycoroutine():
>>  while len(n) > 2:
>>    n = (yield)
>>
>>  throw('RuntimeError' "die!")
> 
> The "throw" is not called from inside the coroutine. It's a method of
> the generator object, and it's used by the calling code. It's similar
> to calling the send method, except that instead of passing a value to
> be returned by the yield expression, it passes an exception to be
> raised inside the coroutine at the yield expression.
> 
> Example:
> 
> def mycoroutine():
>   n = 0
>   while True:
>     try:
>       n = (yield n)
>     except SomeException:
>       n = 42
> 
> coro = mycoroutine()
> coro.next()
> for i in range(100):
>   if i % 6 == 0:
>     coro.send(i % 6)
>   else:
>     coro.throw(SomeException())
> 
> 
>> Also this bit:
>> ***********************
>> If a coroutine returns values, some care is required if exceptions
>> raised with throw() are being handled. If you raise an exception in a
>> coroutine using throw(), the value passed to the next yield in the
>> coroutine will be returned as the result of throw(). If
>> you need this value and forget to save it, it will be lost.
>> ***********************
>>
>> def coroutine():
>>   while True:
>>    line = (yield result)
>>
>>   throw(FooException)
>>
>> where is the question of a 'yield'? You'll exit the coroutine
>> straight away..
> 
> Taking my example from above, after SomeException is caught, the next
> value yielded inside the coroutine will be the return value of the
> coro.throw() call. This may be surprising if you're only expecting
> coro.send() and not coro.throw() to return yielded values.

Thanks, that made it abundantly clear :)



More information about the Python-list mailing list