|
3 | 3 | import io |
4 | 4 | import os |
5 | 5 | import socket |
| 6 | +from threading import Lock |
6 | 7 | from typing import Optional |
7 | 8 |
|
8 | 9 | import aiohttp # lgtm [py/import-and-import-from] |
|
44 | 45 | from ._constants import DEFAULT_KEEPALIVE_TIMEOUT |
45 | 46 | from ._endpoint_helpers import _IOBaseWrapper, _text |
46 | 47 |
|
| 48 | +_session_lock = Lock() |
| 49 | + |
47 | 50 |
|
48 | 51 | class AIOHTTPSession: |
49 | 52 | def __init__( |
@@ -99,14 +102,30 @@ def __init__( |
99 | 102 | # request so don't need proxy manager |
100 | 103 |
|
101 | 104 | async def __aenter__(self): |
102 | | - assert not self._sessions |
| 105 | + with _session_lock: |
| 106 | + self._aexited = False |
103 | 107 |
|
| 108 | + assert not self._sessions |
104 | 109 | return self |
105 | 110 |
|
106 | 111 | async def __aexit__(self, exc_type, exc_val, exc_tb): |
107 | 112 | self._sessions.clear() |
108 | 113 | await self._exit_stack.aclose() |
109 | 114 |
|
| 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 | + |
110 | 129 | def _get_ssl_context(self): |
111 | 130 | return create_urllib3_context() |
112 | 131 |
|
@@ -173,6 +192,11 @@ def _create_connector(self, proxy_url): |
173 | 192 |
|
174 | 193 | async def _get_session(self, proxy_url): |
175 | 194 | 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 | + ) |
176 | 200 | connector = self._create_connector(proxy_url) |
177 | 201 | self._sessions[proxy_url] = ( |
178 | 202 | session |
|
0 commit comments