Skip to content
New issue

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

Patchback/backports/3.10/5fd29467fb63efdfae1ace280cec36b1f8139567/pr 8290 #8310

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/8253.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed "Unclosed client session" when initialization of ClientSession fails -- by :user:`NewGlad`.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Alexander Shorin
Alexander Travov
Alexandru Mihai
Alexey Firsov
Alexey Nikitin
Alexey Popravka
Alexey Stepanov
Amin Etesamian
Expand Down
51 changes: 28 additions & 23 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ def __init__(
max_field_size: int = 8190,
fallback_charset_resolver: _CharsetResolver = lambda r, b: "utf-8",
) -> None:
# We initialise _connector to None immediately, as it's referenced in __del__()
# and could cause issues if an exception occurs during initialisation.
self._connector: Optional[BaseConnector] = None

if loop is None:
if connector is not None:
loop = connector._loop
Expand All @@ -266,29 +270,6 @@ def __init__(
self._base_url.origin() == self._base_url
), "Only absolute URLs without path part are supported"

if connector is None:
connector = TCPConnector(loop=loop)

if connector._loop is not loop:
raise RuntimeError("Session and connector has to use same event loop")

self._loop = loop

if loop.get_debug():
self._source_traceback = traceback.extract_stack(sys._getframe(1))

if cookie_jar is None:
cookie_jar = CookieJar(loop=loop)
self._cookie_jar = cookie_jar

if cookies is not None:
self._cookie_jar.update_cookies(cookies)

self._connector = connector
self._connector_owner = connector_owner
self._default_auth = auth
self._version = version
self._json_serialize = json_serialize
if timeout is sentinel or timeout is None:
self._timeout = DEFAULT_TIMEOUT
if read_timeout is not sentinel:
Expand Down Expand Up @@ -324,6 +305,30 @@ def __init__(
"conflict, please setup "
"timeout.connect"
)

if connector is None:
connector = TCPConnector(loop=loop)

if connector._loop is not loop:
raise RuntimeError("Session and connector has to use same event loop")

self._loop = loop

if loop.get_debug():
self._source_traceback = traceback.extract_stack(sys._getframe(1))

if cookie_jar is None:
cookie_jar = CookieJar(loop=loop)
self._cookie_jar = cookie_jar

if cookies is not None:
self._cookie_jar.update_cookies(cookies)

self._connector = connector
self._connector_owner = connector_owner
self._default_auth = auth
self._version = version
self._json_serialize = json_serialize
self._raise_for_status = raise_for_status
self._auto_decompress = auto_decompress
self._trust_env = trust_env
Expand Down
10 changes: 10 additions & 0 deletions tests/test_client_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,3 +885,13 @@ async def test_build_url_returns_expected_url(
) -> None:
session = await create_session(base_url)
assert session._build_url(url) == expected_url


async def test_instantiation_with_invalid_timeout_value(loop):
loop.set_debug(False)
logs = []
loop.set_exception_handler(lambda loop, ctx: logs.append(ctx))
with pytest.raises(ValueError, match="timeout parameter cannot be .*"):
ClientSession(timeout=1)
# should not have "Unclosed client session" warning
assert not logs
Loading