Runtimeerror event loop is closed asyncio python

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

«RuntimeError: Event loop is closed» when ProactorEventLoop is used #4324

«RuntimeError: Event loop is closed» when ProactorEventLoop is used #4324

Comments

Long story short

When ProactorEventLoop is used, the lack of graceful shutdown in aiohttp results in RuntimeError . (For comparison, when SelectorEventLoop is used, it results in ResourceWarning .) Note that ProactorEventLoop is the default event loop on Windows in Python starting from 3.8.

Maybe the root cause of this issue is the same as of #1925. But the impact is higher ( RuntimeError instead of ResourceWarning ).

Steps to reproduce

import asyncio import sys import aiohttp async def main(): async with aiohttp.ClientSession() as session: async with session.get('https://example.com/'): pass if __name__ == '__main__': if sys.version_info[:2] == (3, 7): asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) asyncio.run(main())

Actual behaviour

sys:1: ResourceWarning: unclosed ResourceWarning: Enable tracemalloc to get the object allocation traceback C:\Programs\Python37\lib\asyncio\proactor_events.py:94: ResourceWarning: unclosed transport > source=self) ResourceWarning: Enable tracemalloc to get the object allocation traceback Exception ignored in: Traceback (most recent call last): File "C:\Programs\Python37\lib\asyncio\proactor_events.py", line 95, in __del__ self.close() File "C:\Programs\Python37\lib\asyncio\proactor_events.py", line 86, in close self._loop.call_soon(self._call_connection_lost, None) File "C:\Programs\Python37\lib\asyncio\base_events.py", line 683, in call_soon self._check_closed() File "C:\Programs\Python37\lib\asyncio\base_events.py", line 475, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed 

Expected behaviour

No exceptions. Maybe warnings, but no exceptions.

Читайте также:  Питон перенести длинную строку

Your environment

aiohttp (client) version: 3.6.2
Python version: 3.7, 3.8
OS: Windows 10

Additional information

I do not know any workaround.

A delay before closing the event loop suggested in the documentation does not help in a bit more complicated example (try to run it several times or add more URLs to the list):

import asyncio import sys import aiohttp URLS = [ # Insert several URLs here, e.g.: "https://www.python.org/ftp/python/", "https://github.com/python/", "https://www.cpan.org/src/5.0/", "https://aiohttp.readthedocs.io/", "https://example.com/", ] async def main(): async with aiohttp.ClientSession() as session: await asyncio.wait([fetch(session, url) for url in URLS]) print("Done.") async def fetch(session: aiohttp.ClientSession, url: str): async with session.get(url): print(f"Requested: url>") if __name__ == '__main__': if sys.version_info[:2] == (3, 7): asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) loop = asyncio.get_event_loop() try: loop.run_until_complete(main()) loop.run_until_complete(asyncio.sleep(2.0)) finally: loop.close()

The text was updated successfully, but these errors were encountered:

import asyncio import aiohttp async def fetch(session, url): async with session.get(url) as response: return await response.text() async def harsheet(): async with aiohttp.ClientSession() as session: json = await fetch(session, "") return (json) async def pyrebase_test(): async with aiohttp.ClientSession() as session: json = await fetch(session, "") return (json) from pprint import pprint loop = asyncio.get_event_loop() group1 = asyncio.gather(harsheet(), pyrebase_test()) results = loop.run_until_complete(group1) pprint(results) loop.close() 

why is this code giving RuntimeError: Event loop is closed error?

This is not s solution, because SelectorEventLoop does not support some features which ProactorEventLoop supports. (See https://docs.python.org/3.8/library/asyncio-platforms.html#windows.)

Yes I did not read the topic clearly, I am sorry.

Running asyncio.get_event_loop().run_until_complete(. ) instead of asyncio.run(. ) doesn’t show the error. Is there any difference between them ?

EDIT: Peraphs there is because run_until_complete does not close the loop while asyncio.run does and calls _ProactorBasePipeTransport.__del__ where it raises the exception, I’ve provided a way to handle it in a dirty manner below.

EDIT (after almost 2 years of fighting with more and more aiohttp bugs)**

As another solution in another issue that is related and more to the root cause, use aiohttp 4.0 or use this code when closing client session #1925, monkey patching is not recommended if another solution exists.

Old monkey patching

I found another solution for this problem if some still having issues with it. This involves directly manipulating the class method itself, it might be dirty in some peoples eyes. This applies to situations where you need to close your loops after a tasks like web apps and other similar situations.

from functools import wraps from asyncio.proactor_events import _ProactorBasePipeTransport def silence_event_loop_closed(func): @wraps(func) def wrapper(self, *args, **kwargs): try: return func(self, *args, **kwargs) except RuntimeError as e: if str(e) != 'Event loop is closed': raise return wrapper _ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__)

EDIT: You may want to do this only on Windows environment to avoid executing it in production (although ProactorEventLoop is not available on Linux, but just in case).

if platform.system() == 'Windows': # Silence the exception here. _ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__)

@paaksing Thank you for that. Those errors were bugging me.

@paaksing the code worked like gold. I have been scratching my hair off for days trying to fix this on my discord bot and then I saw this

# aio-libs/aiohttp#4324 Add get_vlan methods Tidy Up, Black formatting

I don’t understand. Why is this still not fixed even though this issue has been closed for almost 1.5 years?

Can’t you fix it? Can’t you be arsed to fix it? What’s going on?

You’re wrong about this being fixed in python 3.9 though. Guess we’ll wait for python 3.10?

@Aran-Fey It’s fixed for me on 3.9 tho, I honestly don’t know the spaghetti behind this, but this is windows specific issue aswell. The workaround that I posted above should solve your issue.

Can’t you fix it? Can’t you be arsed to fix it? What’s going on?

Also, refer to the comment that closed it and try not to be so rude: #4324 (comment)

@Dreamsorcerer I’ve seen that comment. It contains no useful information. «This will be fixed in master»? Clearly not. What am I supposed to take from that comment? There’s nothing there except maybe the «neither of us uses asyncio on Windows» bit, which doesn’t really mean anything either, but kinda sounds like «We don’t know how to fix it».

@Dreamsorcerer I’ve seen that comment. It contains no useful information. «This will be fixed in master»? Clearly not. What am I supposed to take from that comment? There’s nothing there except maybe the «neither of us uses asyncio on Windows» bit, which doesn’t really mean anything either, but kinda sounds like «We don’t know how to fix it».

Are you reproducing the error on master? If so, then perhaps the issue needs to be reopened, or a new issue made.
If not, the comment said the fix can’t be backported to 3.x, meaning that it is probably not fixed in any public release currently.
If you think this is incorrect and the issue can be fixed in 3.x (I have no knowledge about this issue myself), then feel free to provide a fix in a PR.

In the comment I quoted, and your messaging still sounds aggressive.

@paaksing Why is it really bad? What’s wrong with my recap? Are you saying it’s both a python issue and an aiohttp issue?

I just want to know what will fix this issue, and when that will happen, because I need that information to decide how to deal with this bug. If a bugfix will be released next week, I’ll wait it out. If the bug cannot be fixed before python 3.10, I’ll resort to using one of the various workarounds that have been mentioned. This is crucial information, that, as far as I can tell, isn’t mentioned anywhere in this thread.

So: What is the cause, and how/when can we expect it to be fixed?

Like I said, I don’t want to get off-topic, but I’ll address the «rudeness» thing one last time.

Imagine you’ve given somebody a free gift, but it’s not quite perfect for them, and they turn around and say «Couldn’t you be arsed to add this?». That comes off as rude.

Sure, but that’s not what happened. I came across a bug that still existed despite having been reported a long time ago, so naturally I wanted to know why. One possibility I could think of was that it isn’t fixable. The other possibility I could think of was that nobody cared to fix it. Both are perfectly valid reasons. I don’t care why it isn’t fixed, I just want to know. There’s no judgment involved there.

And that’s all I’m going to say about that matter. If I still sound aggressive, you’ll just have to believe me that it’s not intentional. I’m not here to judge or rage or yell, I’m here to obtain information. (Although it hasn’t worked out very well so far.)

Источник

Оцените статью