Skip to content

Commit 0415a4c

Browse files
authored
Patchback/backports/3.9/5fd29467fb63efdfae1ace280cec36b1f8139567/pr 8290 (#8311)
1 parent f21c6f2 commit 0415a4c

File tree

4 files changed

+50
-35
lines changed

4 files changed

+50
-35
lines changed

CHANGES/8253.bugfix

+1
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

+1
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
Amin Etesamian

aiohttp/client.py

+38-35
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,44 @@ def __init__(
234234
max_field_size: int = 8190,
235235
fallback_charset_resolver: _CharsetResolver = lambda r, b: "utf-8",
236236
) -> None:
237+
# We initialise _connector to None immediately, as it's referenced in __del__()
238+
# and could cause issues if an exception occurs during initialisation.
239+
self._connector: Optional[BaseConnector] = None
240+
if timeout is sentinel or timeout is None:
241+
self._timeout = DEFAULT_TIMEOUT
242+
if read_timeout is not sentinel:
243+
warnings.warn(
244+
"read_timeout is deprecated, " "use timeout argument instead",
245+
DeprecationWarning,
246+
stacklevel=2,
247+
)
248+
self._timeout = attr.evolve(self._timeout, total=read_timeout)
249+
if conn_timeout is not None:
250+
self._timeout = attr.evolve(self._timeout, connect=conn_timeout)
251+
warnings.warn(
252+
"conn_timeout is deprecated, " "use timeout argument instead",
253+
DeprecationWarning,
254+
stacklevel=2,
255+
)
256+
else:
257+
if not isinstance(timeout, ClientTimeout):
258+
raise ValueError(
259+
f"timeout parameter cannot be of {type(timeout)} type, "
260+
"please use 'timeout=ClientTimeout(...)'",
261+
)
262+
self._timeout = timeout
263+
if read_timeout is not sentinel:
264+
raise ValueError(
265+
"read_timeout and timeout parameters "
266+
"conflict, please setup "
267+
"timeout.read"
268+
)
269+
if conn_timeout is not None:
270+
raise ValueError(
271+
"conn_timeout and timeout parameters "
272+
"conflict, please setup "
273+
"timeout.connect"
274+
)
237275
if loop is None:
238276
if connector is not None:
239277
loop = connector._loop
@@ -271,41 +309,6 @@ def __init__(
271309
self._default_auth = auth
272310
self._version = version
273311
self._json_serialize = json_serialize
274-
if timeout is sentinel or timeout is None:
275-
self._timeout = DEFAULT_TIMEOUT
276-
if read_timeout is not sentinel:
277-
warnings.warn(
278-
"read_timeout is deprecated, " "use timeout argument instead",
279-
DeprecationWarning,
280-
stacklevel=2,
281-
)
282-
self._timeout = attr.evolve(self._timeout, total=read_timeout)
283-
if conn_timeout is not None:
284-
self._timeout = attr.evolve(self._timeout, connect=conn_timeout)
285-
warnings.warn(
286-
"conn_timeout is deprecated, " "use timeout argument instead",
287-
DeprecationWarning,
288-
stacklevel=2,
289-
)
290-
else:
291-
if not isinstance(timeout, ClientTimeout):
292-
raise ValueError(
293-
f"timeout parameter cannot be of {type(timeout)} type, "
294-
"please use 'timeout=ClientTimeout(...)'",
295-
)
296-
self._timeout = timeout
297-
if read_timeout is not sentinel:
298-
raise ValueError(
299-
"read_timeout and timeout parameters "
300-
"conflict, please setup "
301-
"timeout.read"
302-
)
303-
if conn_timeout is not None:
304-
raise ValueError(
305-
"conn_timeout and timeout parameters "
306-
"conflict, please setup "
307-
"timeout.connect"
308-
)
309312
self._raise_for_status = raise_for_status
310313
self._auto_decompress = auto_decompress
311314
self._trust_env = trust_env

tests/test_client_session.py

+10
Original file line numberDiff line numberDiff line change
@@ -885,3 +885,13 @@ async def test_build_url_returns_expected_url(
885885
) -> None:
886886
session = await create_session(base_url)
887887
assert session._build_url(url) == expected_url
888+
889+
890+
async def test_instantiation_with_invalid_timeout_value(loop):
891+
loop.set_debug(False)
892+
logs = []
893+
loop.set_exception_handler(lambda loop, ctx: logs.append(ctx))
894+
with pytest.raises(ValueError, match="timeout parameter cannot be .*"):
895+
ClientSession(timeout=1)
896+
# should not have "Unclosed client session" warning
897+
assert not logs

0 commit comments

Comments
 (0)