When an asynchronous generator is about to be garbage collected,
it calls its cached finalizer. The assumption is that the finalizer
will schedule an ``aclose()`` call with the loop that was active
when the iteration started.
For instance, here is how asyncio can be modified to allow
safe finalization of asynchronous generators::
# asyncio/base_events.py
class BaseEventLoop:
def run_forever(self):
...
old_finalizer = sys.get_asyncgen_finalizer()
sys.set_asyncgen_finalizer(self._finalize_asyncgen)
try:
...
finally:
sys.set_asyncgen_finalizer(old_finalizer)
...
def _finalize_asyncgen(self, gen):
self.create_task(gen.aclose())
``sys.set_asyncgen_finalizer`` is thread-specific, so several event
loops running in parallel threads can use it safely.