Runs a sync function ``fn`` in a new greenlet. The sync function can then use :func:`await_` to wait for async functions. :param fn: The sync callable to call. :param \\*args: Positional arguments to pass to the ``fn`` callable. :param \\*\\*kwargs: Keyword arguments to pass to
(
fn: Callable[..., _T],
*args: Any,
_require_await: bool = False,
**kwargs: Any,
)
| 175 | |
| 176 | |
| 177 | async def greenlet_spawn( |
| 178 | fn: Callable[..., _T], |
| 179 | *args: Any, |
| 180 | _require_await: bool = False, |
| 181 | **kwargs: Any, |
| 182 | ) -> _T: |
| 183 | """Runs a sync function ``fn`` in a new greenlet. |
| 184 | |
| 185 | The sync function can then use :func:`await_` to wait for async |
| 186 | functions. |
| 187 | |
| 188 | :param fn: The sync callable to call. |
| 189 | :param \\*args: Positional arguments to pass to the ``fn`` callable. |
| 190 | :param \\*\\*kwargs: Keyword arguments to pass to the ``fn`` callable. |
| 191 | """ |
| 192 | |
| 193 | result: Any |
| 194 | context = _concurrency_shim._AsyncIoGreenlet( |
| 195 | fn, _concurrency_shim.getcurrent() |
| 196 | ) |
| 197 | # runs the function synchronously in gl greenlet. If the execution |
| 198 | # is interrupted by await_, context is not dead and result is a |
| 199 | # coroutine to wait. If the context is dead the function has |
| 200 | # returned, and its result can be returned. |
| 201 | switch_occurred = False |
| 202 | |
| 203 | result = context.switch(*args, **kwargs) |
| 204 | while not context.dead: |
| 205 | switch_occurred = True |
| 206 | try: |
| 207 | # wait for a coroutine from await_ and then return its |
| 208 | # result back to it. |
| 209 | value = await result |
| 210 | except BaseException: |
| 211 | # this allows an exception to be raised within |
| 212 | # the moderated greenlet so that it can continue |
| 213 | # its expected flow. |
| 214 | result = context.throw(*sys.exc_info()) |
| 215 | else: |
| 216 | result = context.switch(value) |
| 217 | |
| 218 | if _require_await and not switch_occurred: |
| 219 | raise exc.AwaitRequired( |
| 220 | "The current operation required an async execution but none was " |
| 221 | "detected. This will usually happen when using a non compatible " |
| 222 | "DBAPI driver. Please ensure that an async DBAPI is used." |
| 223 | ) |
| 224 | return result # type: ignore[no-any-return] |
| 225 | |
| 226 | |
| 227 | class AsyncAdaptedLock: |
no outgoing calls