Ask for a sample code to understand the return value of throw() in a coroutine which returns values

65 Views Asked by At

The book "Python Essential Reference (Fourth Edition)" talks in page 106 about the return value of throw() for a coroutine which returns values, i.e., simultaneously receiving and emitting at the yield statement:

enter image description here

I am trying to write a sample code to take a look at the return value of throw() function in the situation described to see if it is "the value passed to the next yield". The following is the sample code I wrote so far:

def line_splitter(delimiter=None):
    print("Ready to split")
    result = None
    try:
        while True:
            line = (yield result)
            result = line.split(delimiter)
    except GeneratorExit:
        print("Receiver done")
    except RuntimeError:
        print "RuntimeError captured"

s = line_splitter(",")
s.next()
s.send("A,B,C")
r=s.throw(RuntimeError,"You're hosed!")

The problem is, when I run the last line to raise an exception with throw() in the coroutine, the RuntimeError is caught as expected, but a StopIteration exception is generated too and this exception is propagated outwards so I cannot get the result throw() returns. So, how to modify my existing sample code to verify the statements in the text: "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()"? Thanks a lot.

PS: I am using python 2.7.12

1

There are 1 best solutions below

0
On BEST ANSWER

if you 'run out of yields' a StopIteration is raised. a simple (but nonsensical?) workaround would be to just yield the exception (or anything else) back:

def line_splitter(delimiter=None):
    print("Ready to split")
    result = None
    try:
        while True:
            line = yield result
            result = line.split(delimiter)
    except GeneratorExit as exc:
        print("Receiver done")
        yield exc
    except RuntimeError as exc:
        print("RuntimeError captured")
        yield exc

s = line_splitter(",")
next(s)
s.send("A,B,C")
r=s.throw(RuntimeError,"You're hosed!")
print(r)