2

I try to run a coroutine.i write a correct demo:

import asyncio async def outer(): print('in outer') print('waiting for result1') result1 = await phase1() print('waiting for result2') result2 = await phase2(result1) return (result1, result2) async def phase1(): print('in phase1') return 'result1' async def phase2(arg): print('in phase2') return 'result2 derived from {}'.format(arg) event_loop = asyncio.get_event_loop() try: return_value = event_loop.run_until_complete(outer()) print('return value: {!r}'.format(return_value)) finally: event_loop.close() 

I want to know what if the outer function is not a coroutine, so, I remove async, and after that:

import asyncio def outer(): print('in outer') print('waiting for result1') result1 = yield from phase1() print('waiting for result2') result2 = yield from phase2(result1) return (result1, result2) async def phase1(): print('in phase1') return 'result1' async def phase2(arg): print('in phase2') return 'result2 derived from {}'.format(arg) event_loop = asyncio.get_event_loop() try: return_value = event_loop.run_until_complete(outer()) print('return value: {!r}'.format(return_value)) finally: event_loop.close() 

then i run this event loop ,I find this error.how to explain this error?it not allowed to use a usual function to call coroutine? I used to thought yield from can be used in a usual funciton,but here,absolutly,it could't.who can tell me the reason?

5
  • obviously,this error tell me yield from only used in a coroutine.but I want to know why,because,it can used in a usual generator. Commented Jan 19, 2017 at 11:38
  • 1
    A coroutine object created with async def simply isn't a generator, so you can't yield from it. You can extract a generator from it and yield from that, e.g. yield from phase1().__await__(), but I can't see a reason why you would ever want to. Commented Jan 19, 2017 at 11:41
  • 1
    As a general note, whenever you ask about an error, please include the full traceback of the error. Most errors can be understood by carefully reading the traceback. Commented Jan 19, 2017 at 11:43
  • @SvenMarnach sorry, thank u for ur friendly suggestion,I just sign up stackorverflow just now,this is my first question,i just don't know the rule of stackoverflow,i will remember it.3Q Commented Jan 19, 2017 at 11:53
  • @michael: you can still edit your question and add the traceback. Commented Feb 12, 2017 at 20:43

1 Answer 1

3

Python 3.5+ requires coroutines to be defined with async def or @asyncio.coroutine for many operations (for example for await x) and will throw exceptions if you try to pass anything that does not conform to this.

See inspect.isawaitable(object) in python 3.5 docs and source code:

def isawaitable(object): """Return true if object can be passed to an ``await`` expression.""" return (isinstance(object, types.CoroutineType) or isinstance(object, types.GeneratorType) and bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or isinstance(object, collections.abc.Awaitable)) 
Sign up to request clarification or add additional context in comments.

1 Comment

You're welcome. If this is the correct answer, hit the check mark icon to accept it :-) see: stackoverflow.com/help/someone-answers . Good luck in Stack Overflow!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.