coroutine function vs. function returning awaitable
Hi, I have a 2-part question: 1) Say you have a function that returns an awaitable (but not a coroutine object). Are there any advantages or disadvantages to replacing this with a function for which asyncio.iscoroutinefunction() returns True and asyncio.iscoroutine() returns True for the return value? An advantage might be, say, additional checks that asyncio performs. 2) If there are advantages, is there a straightforward way to construct such a replacement? In the case I have in mind (from an open source project), the "function" you'd be starting with is the class constructor for an async context manager that is also awaitable. So the class has both __aenter__ and __await__ methods. As an example naive attempt, the following _wouldn't_ work: @asyncio.coroutine def connect(): return AsyncConnectManager() The reason this doesn't work is that wrapping connect() in @asyncio.coroutine() means the return value is no longer an async context manager (it no longer has an __aenter__ method). You have to await to get the underlying async context manager. Thanks, --Chris
Re (1), there are only two places where asyncio calls `iscouroutinefunction()`, and in both cases it raises a TypeError to remind the user that a coroutine/awaitable object is required. So, it doesn't really offer much of an advantage and I wouldn't worry about it. On Thu, Nov 2, 2017 at 4:51 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
Hi,
I have a 2-part question:
1) Say you have a function that returns an awaitable (but not a coroutine object). Are there any advantages or disadvantages to replacing this with a function for which asyncio.iscoroutinefunction() returns True and asyncio.iscoroutine() returns True for the return value? An advantage might be, say, additional checks that asyncio performs.
2) If there are advantages, is there a straightforward way to construct such a replacement? In the case I have in mind (from an open source project), the "function" you'd be starting with is the class constructor for an async context manager that is also awaitable. So the class has both __aenter__ and __await__ methods.
As an example naive attempt, the following _wouldn't_ work:
@asyncio.coroutine def connect(): return AsyncConnectManager()
The reason this doesn't work is that wrapping connect() in @asyncio.coroutine() means the return value is no longer an async context manager (it no longer has an __aenter__ method). You have to await to get the underlying async context manager.
Thanks, --Chris _______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
Thanks. And how about making asyncio.iscoroutine() return True for the return value? It looks like asyncio calls that one in a half-dozen places or so. —Chris On Thu, Nov 2, 2017 at 7:15 PM Guido van Rossum <guido@python.org> wrote:
Re (1), there are only two places where asyncio calls `iscouroutinefunction()`, and in both cases it raises a TypeError to remind the user that a coroutine/awaitable object is required. So, it doesn't really offer much of an advantage and I wouldn't worry about it.
On Thu, Nov 2, 2017 at 4:51 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
Hi,
I have a 2-part question:
1) Say you have a function that returns an awaitable (but not a coroutine object). Are there any advantages or disadvantages to replacing this with a function for which asyncio.iscoroutinefunction() returns True and asyncio.iscoroutine() returns True for the return value? An advantage might be, say, additional checks that asyncio performs.
2) If there are advantages, is there a straightforward way to construct such a replacement? In the case I have in mind (from an open source project), the "function" you'd be starting with is the class constructor for an async context manager that is also awaitable. So the class has both __aenter__ and __await__ methods.
As an example naive attempt, the following _wouldn't_ work:
@asyncio.coroutine def connect(): return AsyncConnectManager()
The reason this doesn't work is that wrapping connect() in @asyncio.coroutine() means the return value is no longer an async context manager (it no longer has an __aenter__ method). You have to await to get the underlying async context manager.
Thanks, --Chris
_______________________________________________
Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
iscoroutine() is usually used to turn something into a Future. Is that what you want? (TBH I'm not sure why you're asking all this.) On Thu, Nov 2, 2017 at 7:49 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
Thanks. And how about making asyncio.iscoroutine() return True for the return value? It looks like asyncio calls that one in a half-dozen places or so.
—Chris
On Thu, Nov 2, 2017 at 7:15 PM Guido van Rossum <guido@python.org> wrote:
Re (1), there are only two places where asyncio calls `iscouroutinefunction()`, and in both cases it raises a TypeError to remind the user that a coroutine/awaitable object is required. So, it doesn't really offer much of an advantage and I wouldn't worry about it.
On Thu, Nov 2, 2017 at 4:51 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
Hi,
I have a 2-part question:
1) Say you have a function that returns an awaitable (but not a coroutine object). Are there any advantages or disadvantages to replacing this with a function for which asyncio.iscoroutinefunction() returns True and asyncio.iscoroutine() returns True for the return value? An advantage might be, say, additional checks that asyncio performs.
2) If there are advantages, is there a straightforward way to construct such a replacement? In the case I have in mind (from an open source project), the "function" you'd be starting with is the class constructor for an async context manager that is also awaitable. So the class has both __aenter__ and __await__ methods.
As an example naive attempt, the following _wouldn't_ work:
@asyncio.coroutine def connect(): return AsyncConnectManager()
The reason this doesn't work is that wrapping connect() in @asyncio.coroutine() means the return value is no longer an async context manager (it no longer has an __aenter__ method). You have to await to get the underlying async context manager.
Thanks, --Chris
_______________________________________________
Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
-- --Guido van Rossum (python.org/~guido)
I'm asking because a project I've been contributing to has this "bug" reported: https://github.com/aaugustin/websockets/issues/300 So I'm trying to see if it needs to be fixed or if it can be left alone. More generally, this made me wonder if there are any advantages to ensuring that asyncio.iscoroutine() returns True for an object if the object is meant to be used like a coroutine object. (For example, perhaps this is what will give you the nice "coroutine object hasn't been awaited" warnings.) It looks like types.coroutine() might be the answer if there are advantages (but I haven't tried it): https://www.python.org/dev/peps/pep-0492/#types-coroutine --Chris On Thu, Nov 2, 2017 at 8:16 PM, Guido van Rossum <guido@python.org> wrote:
iscoroutine() is usually used to turn something into a Future. Is that what you want? (TBH I'm not sure why you're asking all this.)
On Thu, Nov 2, 2017 at 7:49 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
Thanks. And how about making asyncio.iscoroutine() return True for the return value? It looks like asyncio calls that one in a half-dozen places or so.
—Chris
On Thu, Nov 2, 2017 at 7:15 PM Guido van Rossum <guido@python.org> wrote:
Re (1), there are only two places where asyncio calls `iscouroutinefunction()`, and in both cases it raises a TypeError to remind the user that a coroutine/awaitable object is required. So, it doesn't really offer much of an advantage and I wouldn't worry about it.
On Thu, Nov 2, 2017 at 4:51 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
Hi,
I have a 2-part question:
1) Say you have a function that returns an awaitable (but not a coroutine object). Are there any advantages or disadvantages to replacing this with a function for which asyncio.iscoroutinefunction() returns True and asyncio.iscoroutine() returns True for the return value? An advantage might be, say, additional checks that asyncio performs.
2) If there are advantages, is there a straightforward way to construct such a replacement? In the case I have in mind (from an open source project), the "function" you'd be starting with is the class constructor for an async context manager that is also awaitable. So the class has both __aenter__ and __await__ methods.
As an example naive attempt, the following _wouldn't_ work:
@asyncio.coroutine def connect(): return AsyncConnectManager()
The reason this doesn't work is that wrapping connect() in @asyncio.coroutine() means the return value is no longer an async context manager (it no longer has an __aenter__ method). You have to await to get the underlying async context manager.
Thanks, --Chris
_______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
-- --Guido van Rossum (python.org/~guido)
It looks like what you have in that library is something that's awaitable but not a coroutine. That's totally fine. (Other examples exist, e.g. Futures!) On Thu, Nov 2, 2017 at 8:33 PM, Chris Jerdonek <chris.jerdonek@gmail.com> wrote:
I'm asking because a project I've been contributing to has this "bug" reported:
https://github.com/aaugustin/websockets/issues/300
So I'm trying to see if it needs to be fixed or if it can be left alone.
More generally, this made me wonder if there are any advantages to ensuring that asyncio.iscoroutine() returns True for an object if the object is meant to be used like a coroutine object. (For example, perhaps this is what will give you the nice "coroutine object hasn't been awaited" warnings.)
It looks like types.coroutine() might be the answer if there are advantages (but I haven't tried it): https://www.python.org/dev/peps/pep-0492/#types-coroutine
--Chris
iscoroutine() is usually used to turn something into a Future. Is that what you want? (TBH I'm not sure why you're asking all this.)
On Thu, Nov 2, 2017 at 7:49 PM, Chris Jerdonek <chris.jerdonek@gmail.com
wrote:
Thanks. And how about making asyncio.iscoroutine() return True for the return value? It looks like asyncio calls that one in a half-dozen
On Thu, Nov 2, 2017 at 8:16 PM, Guido van Rossum <guido@python.org> wrote: places or
so.
—Chris
On Thu, Nov 2, 2017 at 7:15 PM Guido van Rossum <guido@python.org> wrote:
Re (1), there are only two places where asyncio calls `iscouroutinefunction()`, and in both cases it raises a TypeError to
remind
the user that a coroutine/awaitable object is required. So, it doesn't really offer much of an advantage and I wouldn't worry about it.
On Thu, Nov 2, 2017 at 4:51 PM, Chris Jerdonek < chris.jerdonek@gmail.com> wrote:
Hi,
I have a 2-part question:
1) Say you have a function that returns an awaitable (but not a coroutine object). Are there any advantages or disadvantages to replacing this with a function for which asyncio.iscoroutinefunction() returns True and asyncio.iscoroutine() returns True for the return value? An advantage might be, say, additional checks that asyncio performs.
2) If there are advantages, is there a straightforward way to construct such a replacement? In the case I have in mind (from an open source project), the "function" you'd be starting with is the class constructor for an async context manager that is also awaitable. So the class has both __aenter__ and __await__ methods.
As an example naive attempt, the following _wouldn't_ work:
@asyncio.coroutine def connect(): return AsyncConnectManager()
The reason this doesn't work is that wrapping connect() in @asyncio.coroutine() means the return value is no longer an async context manager (it no longer has an __aenter__ method). You have to await to get the underlying async context manager.
Thanks, --Chris
_______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
-- --Guido van Rossum (python.org/~guido)
-- --Guido van Rossum (python.org/~guido)
participants (2)
-
Chris Jerdonek
-
Guido van Rossum