1

I am trying to feed a dictionary by using .send(). And my code snippet is below

def coroutine(func):
    def start(*args, **kwargs):
        cr = func(*args, **kwargs)
        next(cr)
        return cr
    return start

@coroutine
def putd(di):

    print("via coroutines adding a key : value to dictionary")

    try:
        item = yield
        for key, value in item.items():
            if key in di:
                print("Key : {0} already exists".format(key))
            else:
                di[key] = value
        print(di)
    except StopIteration :
        print("yield frame got closed")


di = {}
gobj = putd(di)
gobj.send({"plan" : "shuttle"})
gobj.close()

And I believe I am handling the exception properly but still I am getting StopIteration exception.

scratch.py
Traceback (most recent call last):
via coroutines adding a key : value to dictionary
{'plan': 'shuttle'}
File "scratch.py", line 39, in <module>
    gobj.send({"plan" : "shuttle"})
StopIteration

Process finished with exit code 1

Am I not handling that exception properly or am I missing something ? ANy help greatly appreciated.

1 Answer 1

3

Your coroutine exits after first send/yield. That generates a StopIteration and you cannot handle it in the coroutine itself, but only when invoking send. From the docs:

The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value.

@coroutine
def putd(di):

    print("via coroutines adding a key : value to dictionary")

    try:
        item = yield
        for key, value in item.items():
            if key in di:
                print("Key : {0} already exists".format(key))
            else:
                di[key] = value
        print(di)
    except StopIteration :
        print("yield frame got closed")
    # here is an implicit  return None  which terminates the coroutine

I guess you want to keep the coroutine alive accepting as many sends as you want until an explicit close:

@coroutine
def putd(di):

    print("via coroutines adding a key : value to dictionary")

    try:
        while True:
            item = yield
            for key, value in item.items():
                if key in di: 
                    print("Key : {0} already exists".format(key))
                else:
                    di[key] = value
            print(di)
    except GeneratorExit:
        print("yield frame got closed")

Please note that now the GeneratorExit exception is caught.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent!!, Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.