Yury Selivanov wrote:
It's important to at least have 'iscoroutine' -- to check that the object is a coroutine function. A typical use-case would be a web framework that lets you to bind coroutines to specific http methods/paths:
@http.get('/spam') async def handle_spam(request): ...
The other thing is that it's easy to implement this function for CPython: just check for CO_COROUTINE flag.
But isn't that too restrictive? Any function that returns an awaitable object would work in the above case.
One of the most frequent mistakes that people make when using generators as coroutines is forgetting to use ``yield from``::
I think it's a mistake that a lot of beginners may make at some point (and in this sense it's frequent). I really doubt that once you were hit by it more than two times you would make it again.
What about when you change an existing non-suspendable function to make it suspendable, and have to deal with the ripple-on effects of that? Seems to me that affects everyone, not just beginners.
3. ``yield from`` does not accept coroutine objects from plain Python generators (*not* generator-based coroutines.)
What exactly are "coroutine objects from plain Python generators"?)
# *Not* decorated with @coroutine def some_algorithm_impl(): yield 1 yield from native_coroutine() # <- this is a bug
So what you really mean is "yield-from, when used inside a function that doesn't have @coroutine applied to it, will not accept a coroutine object", is that right? If so, I think this part needs re-wording, because it sounded like you meant something quite different. I'm not sure I like this -- it seems weird that applying a decorator to a function should affect the semantics of something *inside* the function -- especially a piece of built-in syntax such as 'yield from'. It's similar to the idea of replacing 'async def' with a decorator, which you say you're against. BTW, by "coroutine object", do you mean only objects returned by an async def function, or any object having an __await__ method? I think a lot of things would be clearer if we could replace the term "coroutine object" with "awaitable object" everywhere.
``yield from`` does not accept *native coroutine objects* from regular Python generators
It's the "from" there that's confusing -- it sounds like you're talking about where the argument to yield-from comes from, rather than where the yield-from expression resides. In other words, we though you were proposing to disallow *this*: # *Not* decorated with @coroutine def some_algorithm_impl(): yield 1 yield from iterator_implemented_by_generator() I hope to agree that this is a perfectly legitimate thing to do, and should remain so? -- Greg