Awaits an async function in a sync method. The sync method must be inside a :func:`greenlet_spawn` context. :func:`await_` calls cannot be nested. :param awaitable: The coroutine to call.
(awaitable: Awaitable[_T])
| 145 | |
| 146 | |
| 147 | def await_(awaitable: Awaitable[_T]) -> _T: |
| 148 | """Awaits an async function in a sync method. |
| 149 | |
| 150 | The sync method must be inside a :func:`greenlet_spawn` context. |
| 151 | :func:`await_` calls cannot be nested. |
| 152 | |
| 153 | :param awaitable: The coroutine to call. |
| 154 | |
| 155 | """ |
| 156 | # this is called in the context greenlet while running fn |
| 157 | current = _concurrency_shim.getcurrent() |
| 158 | if not getattr(current, "__sqlalchemy_greenlet_provider__", False): |
| 159 | _safe_cancel_awaitable(awaitable) |
| 160 | |
| 161 | raise exc.MissingGreenlet( |
| 162 | "greenlet_spawn has not been called; can't call await_() " |
| 163 | "here. Was IO attempted in an unexpected place?" |
| 164 | ) |
| 165 | |
| 166 | # returns the control to the driver greenlet passing it |
| 167 | # a coroutine to run. Once the awaitable is done, the driver greenlet |
| 168 | # switches back to this greenlet with the result of awaitable that is |
| 169 | # then returned to the caller (or raised as error) |
| 170 | assert current.parent |
| 171 | return current.parent.switch(awaitable) # type: ignore[no-any-return] |
| 172 | |
| 173 | |
| 174 | await_only = await_ # old name. deprecated on 2.2 |