[Async-sig] question re: loop.shutdown_asyncgens()

Chris Jerdonek chris.jerdonek at gmail.com
Wed Aug 2 19:30:06 EDT 2017


On Fri, Jul 28, 2017 at 1:58 PM, Yury Selivanov <yselivanov at gmail.com> wrote:
> On Jul 28, 2017, 4:57 PM -0400, Chris Jerdonek <chris.jerdonek at gmail.com>, wrote:
>> Thanks! I'll try to find time to propose a PR.
>>
>> Also, for suggestions around the new API, would you prefer that be posted to PR #465, or can it be done here?
>
> I think we can discuss it here, but up to you.
>

So here are some of my thoughts related to exposing an API for
asyncio.run() and friends:

I think it would be helpful if, in addition to asyncio.run(), the API
made some attempt to expose building blocks (where natural) so that if
the user wants to do something slightly different from what run()
supports, they don't need to copy from the internal implementation.
I'm including one suggestion for this below.

Related to this, I'd like to ask that the following two use cases be
contemplated / relatively easy to support through the API. It doesn't
need to be through the top-level functions like run(), but maybe by
using the building blocks:

1) creating loops "on-the-fly" in different threads, like I asked
about in this thread:
https://mail.python.org/pipermail/async-sig/2017-July/000348.html

The PR #465 discussion currently seems to be leaning away from
supporting this in any way.

2) creating fresh loops for individual unittest TestCase methods /
subTests, without mandating a specific approach. Different approaches
that I think should be supportable through the API include
user-implemented TestCase method decorators that create and destroy a
loop using the API, as well as doing this through TestCase's setUp()
and tearDown().

One "building block" that I think should be exposed is a context
manager for managing the lifetime of a loop. It could look something
like this:

    @contextmanager
    def new_loop(debug=False):
        loop = events.new_event_loop()
        try:
            events.set_event_loop(loop)

            if debug:
                loop.set_debug(True)

            yield loop
        finally:
            _cleanup(loop)

Both run() and run_forever() in the latest patch posted on PR #465 can
be implemented in terms of this context manager without changing the
logic:

https://github.com/python/asyncio/pull/465/commits/275072a2fbae0c98619597536d85a65bd72d706b

Even if it was decided not to make this context manager public, I
think the implementations of run() / run_forever() / etc. would
benefit by making the commonalities between them clearer, etc.

Thanks,
--Chris


More information about the Async-sig mailing list