Creating resolved Future without an event loop (original) (raw)
I have some old code in a __ init __ file that does:
LOGGING_DISABLED: LOGGING_STATUS = asyncio.Future()
LOGGING_DISABLED.set_result("DISABLED")
LOGGING_IGNORED: LOGGING_STATUS = asyncio.Future()
LOGGING_IGNORED.set_result("IGNORED")
LOGGING_RUNNING: LOGGING_STATUS = asyncio.Future()
LOGGING_RUNNING.set_result("RUNNING")
never python complainsDeprecationWarning: There is no current event loop
How do I make a resolved Future without an event loop.
I really do not want to make an event loop just to close it again 6 lines later
guido (Guido van Rossum) May 5, 2025, 5:24pm 2
That doesn’t look like valid Python code to me, and it doesn’t mention Futures at all. Maybe it’s logging output? Could you quote the actual code instead?
I assume “never” → “newer”.
It is valid code. I assume that LOGGING_STATUS
is some static type:
In [39]: import asyncio
In [40]: LOGGING_STATUS = int
In [41]: LOGGING_DISABLED: LOGGING_STATUS = asyncio.Future()
...: LOGGING_DISABLED.set_result("DISABLED")
...: LOGGING_IGNORED: LOGGING_STATUS = asyncio.Future()
...: LOGGING_IGNORED.set_result("IGNORED")
...: LOGGING_RUNNING: LOGGING_STATUS = asyncio.Future()
...: LOGGING_RUNNING.set_result("RUNNING")
<ipython-input-41-b566686b297e>:1: DeprecationWarning: There is no current event loop
LOGGING_DISABLED: LOGGING_STATUS = asyncio.Future()
guido (Guido van Rossum) May 5, 2025, 9:07pm 4
Ah, I didn’t realize the : LOGGING_STATUS
parts were type annotations.
Anyways, @pebl: Why do you want variables that are resolved futures, disconnected from any loop? How are these used? That DeprecationWarning isn’t going to be removed and will only get worse in the future, so the best thing to do is figure out what that code was trying to do and find a different way to express it.
graingert (Thomas Grainger) May 6, 2025, 9:45am 5
instead of a Future (which you should basically never use directly - it’s only for low level code to translate between callbacks/protocols and tasks) use an Event wrapped with an awaitable class:
class MyAwaitable(Generic[T]):
def __init__(self):
self._result: T | None = None
self._event = asyncio.Event()
async def wait(self) -> T:
await self._event.wait()
return cast(T, self._result)
def set_result(self, result: T) -> None:
if self._event.is_set():
raise RuntimeError("Invalid state")
self._result = result
self._event.set()
def __await__(self) -> Generator[T]:
return self.wait().__await__()