Skip to content

Commit 5fd2946

Browse files
authored
Fix for #8253 "Unclosed client session" when initialization fails (#8290)
1 parent 28d026e commit 5fd2946

File tree

4 files changed

+20
-10
lines changed

4 files changed

+20
-10
lines changed

CHANGES/8253.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed "Unclosed client session" when initialization of ClientSession fails -- by :user:`NewGlad`.

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Alexander Shorin
2727
Alexander Travov
2828
Alexandru Mihai
2929
Alexey Firsov
30+
Alexey Nikitin
3031
Alexey Popravka
3132
Alexey Stepanov
3233
Almaz Salakhov

aiohttp/client.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ def __init__(
243243
max_field_size: int = 8190,
244244
fallback_charset_resolver: _CharsetResolver = lambda r, b: "utf-8",
245245
) -> None:
246+
# We initialise _connector to None immediately, as it's referenced in __del__()
247+
# and could cause issues if an exception occurs during initialisation.
248+
self._connector: Optional[BaseConnector] = None
246249
if base_url is None or isinstance(base_url, URL):
247250
self._base_url: Optional[URL] = base_url
248251
else:
@@ -253,12 +256,20 @@ def __init__(
253256

254257
loop = asyncio.get_running_loop()
255258

259+
if timeout is sentinel or timeout is None:
260+
timeout = DEFAULT_TIMEOUT
261+
if not isinstance(timeout, ClientTimeout):
262+
raise ValueError(
263+
f"timeout parameter cannot be of {type(timeout)} type, "
264+
"please use 'timeout=ClientTimeout(...)'",
265+
)
266+
self._timeout = timeout
267+
256268
if connector is None:
257269
connector = TCPConnector()
258-
259270
# Initialize these three attrs before raising any exception,
260271
# they are used in __del__
261-
self._connector: Optional[BaseConnector] = connector
272+
self._connector = connector
262273
self._loop = loop
263274
if loop.get_debug():
264275
self._source_traceback: Optional[traceback.StackSummary] = (
@@ -281,14 +292,6 @@ def __init__(
281292
self._default_auth = auth
282293
self._version = version
283294
self._json_serialize = json_serialize
284-
if timeout is sentinel or timeout is None:
285-
timeout = DEFAULT_TIMEOUT
286-
if not isinstance(timeout, ClientTimeout):
287-
raise ValueError(
288-
f"timeout parameter cannot be of {type(timeout)} type, "
289-
"please use 'timeout=ClientTimeout(...)'",
290-
)
291-
self._timeout = timeout
292295
self._raise_for_status = raise_for_status
293296
self._auto_decompress = auto_decompress
294297
self._trust_env = trust_env

tests/test_client_session.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,3 +841,8 @@ async def test_build_url_returns_expected_url(
841841
) -> None:
842842
session = await create_session(base_url)
843843
assert session._build_url(url) == expected_url
844+
845+
846+
async def test_instantiation_with_invalid_timeout_value():
847+
with pytest.raises(ValueError, match="timeout parameter cannot be .*"):
848+
ClientSession(timeout=1)

0 commit comments

Comments
 (0)