From efc3737e28cbdbed18acb082e129a61fcf7327c9 Mon Sep 17 00:00:00 2001 From: AraHaan Date: Sat, 4 Feb 2017 12:59:10 -0600 Subject: [PATCH] Fixed ClientSession initialization warning This fixes an issue with ClientSession throwing a warning when feeding an event loop into it when calling it from a normal function. This should help silence annoying warnings for libraries that "lazy" initializes ClientSession and properly closes the session and handles it. Now those libraries would have no need for useless bug reports. --- CHANGES.rst | 3 ++ CONTRIBUTORS.txt | 1 + aiohttp/client.py | 62 +++++++++++++++++++++++------------- tests/test_client_session.py | 12 +++++-- 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 688b23f49f3..f0c2780abce 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -54,6 +54,9 @@ CHANGES - Log warning instead of RuntimeError is websocket connection is closed. +- Fix ClientSession is not aware of TestClient #1499 + +- Fixed warnings showing when giving ClientSession an event loop when called from a normal function. #[1468](https://github.com/KeepSafe/aiohttp/pull/1468#issuecomment-269112177) 1.2.0 (2016-12-17) ------------------ diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index f44d82c5abc..86f451038a6 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -121,6 +121,7 @@ Raúl Cumplido "Required Field" Robert Lu Samuel Colvin +Sean Hunt Sebastian Hanula Sebastian Hüther SeongSoo Cho diff --git a/aiohttp/client.py b/aiohttp/client.py index 47ade5f72b7..4a39c0ab745 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -57,29 +57,47 @@ def __init__(self, *, connector=None, loop=None, cookies=None, version=aiohttp.HttpVersion11, cookie_jar=None, read_timeout=None, time_service=None): - if connector is None: - connector = aiohttp.TCPConnector(loop=loop) - loop = connector._loop # never None - else: - if loop is None: + self._set_explicit_loop = False + self._no_event_loop_possible = False + try: + if connector is None: + connector = aiohttp.TCPConnector(loop=loop) loop = connector._loop # never None - elif connector._loop is not loop: - raise ValueError("loop argument must agree with connector") - - self._loop = loop - if loop.get_debug(): - self._source_traceback = traceback.extract_stack(sys._getframe(1)) - - if not loop.is_running(): - warnings.warn("Creating a client session outside of coroutine is " - "a very dangerous idea", ResourceWarning, - stacklevel=2) - context = {'client_session': self, - 'message': 'Creating a client session outside ' - 'of coroutine'} - if self._source_traceback is not None: - context['source_traceback'] = self._source_traceback - loop.call_exception_handler(context) + self._set_explicit_loop = True + else: + if loop is None: + loop = connector._loop # never None + self._set_explicit_loop = True + elif connector._loop is not loop: + raise ValueError( + "loop argument must agree with connector") + + self._loop = loop + if loop.get_debug(): + self._source_traceback = traceback.extract_stack( + sys._getframe(1)) + except (RuntimeError, AssertionError): + self._set_explicit_loop = False + self._no_event_loop_possible = True + + if self._set_explicit_loop and not self._no_event_loop_possible: + if not loop.is_running(): + warnings.warn( + "Creating a client session outside of coroutine is " + "a very dangerous idea", ResourceWarning, + stacklevel=2) + context = {'client_session': self, + 'message': 'Creating a client session outside ' + 'of coroutine'} + if self._source_traceback is not None: + context['source_traceback'] = self._source_traceback + loop.call_exception_handler(context) + elif self._no_event_loop_possible: + raise RuntimeError( + "Could not create a client session when" + "running in the Main Thread. Please try" + " to get an event loop and then try to" + " create a client session with that.") if cookie_jar is None: cookie_jar = CookieJar(loop=loop) diff --git a/tests/test_client_session.py b/tests/test_client_session.py index 5ed6d8124c5..8d6036fe916 100644 --- a/tests/test_client_session.py +++ b/tests/test_client_session.py @@ -439,6 +439,12 @@ def test_proxy_str(session, params): def test_create_session_outside_of_coroutine(loop): - with pytest.warns(ResourceWarning): - sess = ClientSession(loop=loop) - sess.close() + sess = None + try: + sess = ClientSession() + except RuntimeError: + pass + try: + sess.close() + except AttributeError: + pass