|
3 | 3 | from contextlib import contextmanager |
4 | 4 | from dataclasses import dataclass |
5 | 5 | from queue import Empty, Queue |
6 | | -from typing import Optional, Union |
| 6 | +from typing import Iterator, Optional, Union |
7 | 7 |
|
8 | 8 | import requests.adapters |
| 9 | +from typing_extensions import Self |
9 | 10 |
|
10 | 11 | from fundus.logging import create_logger |
11 | 12 | from fundus.utils.events import __EVENTS__ |
@@ -170,11 +171,26 @@ def close_current_session(self) -> None: |
170 | 171 | self._session = None |
171 | 172 |
|
172 | 173 | @contextmanager |
173 | | - def context(self, **kwargs): |
174 | | - """Context manager to temporarily overwrite session parameters. |
| 174 | + def context(self, **kwargs) -> Iterator[Self]: |
| 175 | + """Thread-safe context manager for temporarily overriding session configuration. |
| 176 | +
|
| 177 | + This context manager temporarily replaces the current `CONFIG` instance with a new one |
| 178 | + constructed from the provided keyword arguments and clears the current session. |
| 179 | + Subsequent calls to `get_session()` will use the new configuration, while existing |
| 180 | + sessions remain unchanged. Internally we use a reentrant lock (RLock) to allow nested |
| 181 | + contexts within the same thread. |
| 182 | +
|
| 183 | + To prevent deadlocks, attempting to open a new context in another thread while already in |
| 184 | + a context raises an `AssertionError`.` |
| 185 | +
|
| 186 | + Args: |
| 187 | + **kwargs: Keyword arguments corresponding to `CONFIG` parameters. |
175 | 188 |
|
176 | 189 | Returns: |
177 | | - SessionHandler: The session handler instance. |
| 190 | + SessionHandler: The current session handler instance with the temporary configuration. |
| 191 | +
|
| 192 | + Raises: |
| 193 | + AssertionError: If a context is already active in another thread. |
178 | 194 | """ |
179 | 195 |
|
180 | 196 | if self._context_lock.acquire(blocking=False): |
|
0 commit comments