Skip to content

Commit a389782

Browse files
committed
add raising mechanism + test
1 parent d5ff89f commit a389782

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

aiobotocore/httpsession.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io
44
import os
55
import socket
6+
from threading import Lock
67
from typing import Optional
78

89
import aiohttp # lgtm [py/import-and-import-from]
@@ -44,6 +45,8 @@
4445
from ._constants import DEFAULT_KEEPALIVE_TIMEOUT
4546
from ._endpoint_helpers import _IOBaseWrapper, _text
4647

48+
_session_lock = Lock()
49+
4750

4851
class AIOHTTPSession:
4952
def __init__(
@@ -99,14 +102,30 @@ def __init__(
99102
# request so don't need proxy manager
100103

101104
async def __aenter__(self):
102-
assert not self._sessions
105+
with _session_lock:
106+
self._aexited = False
103107

108+
assert not self._sessions
104109
return self
105110

106111
async def __aexit__(self, exc_type, exc_val, exc_tb):
107112
self._sessions.clear()
108113
await self._exit_stack.aclose()
109114

115+
with _session_lock:
116+
self._aexited = True
117+
118+
@property
119+
def _can_create_session(self) -> bool:
120+
"""Check if a new client session can be created.
121+
122+
This is true for two cases:
123+
- We are inside the context manager of the class.
124+
- We have never attempted to enter the context manager.
125+
"""
126+
with _session_lock:
127+
return not getattr(self, '_aexited', False)
128+
110129
def _get_ssl_context(self):
111130
return create_urllib3_context()
112131

@@ -173,6 +192,11 @@ def _create_connector(self, proxy_url):
173192

174193
async def _get_session(self, proxy_url):
175194
if not (session := self._sessions.get(proxy_url)):
195+
if not self._can_create_session:
196+
raise RuntimeError(
197+
f'Cannot create a new {aiohttp.ClientSession.__name__} '
198+
'when context manager was exited.'
199+
)
176200
connector = self._create_connector(proxy_url)
177201
self._sessions[proxy_url] = (
178202
session

tests/botocore_tests/unit/test_session.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,21 @@ async def test_can_create_client(self, session):
152152
async with sts_client_context as sts_client:
153153
assert isinstance(sts_client, client.AioBaseClient)
154154

155+
async def test_cannot_create_client_sessions_outside_context(
156+
self, session
157+
):
158+
s3_client_context = session.create_client('s3', 'us-west-2')
159+
160+
async with s3_client_context as s3_client:
161+
pass
162+
163+
with pytest.raises(
164+
botocore.exceptions.HTTPClientError,
165+
match='Cannot create a new ClientSession when context manager was'
166+
' exited',
167+
):
168+
await s3_client.list_buckets()
169+
155170
async def test_credential_provider_not_called_when_creds_provided(
156171
self, session
157172
):

0 commit comments

Comments
 (0)