Author lukasz.langa
Recipients asvetlov, lukasz.langa, simonw, uriyyo, yselivanov
Date 2021-10-08.21:16:41
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1633727802.06.0.781167329942.issue45416@roundup.psfhosted.org>
In-reply-to
Content
Issue confirmed. The problem is that `Condition.__init__` compares its own loop with Lock's internal `_loop` attribute. That attribute is set to None unless the lock waited to be acquired.

uriyyo, Andrew, Yury, since it's pretty likely that Lock objects will now have `_loop` set to None, I think the check for "loop agreement" in Condition is kind of useless. So I propose to simply remove it. It's the only such check in all of asyncio.

If you insist on keeping the loop check, it should special-case `_loop is None`.

Simon, thanks for your detailed report! As a backwards-compatible workaround till we get a fix in, your user code can do the following:

>>> l = asyncio.Lock()
>>> getattr(l, '_get_loop', lambda: None)()
<_UnixSelectorEventLoop running=True closed=False debug=False>

You can use such lock without issues now:

>>> asyncio.Condition(l)
<asyncio.locks.Condition object at 0x10c05bee0 [unlocked]>

Alternatively, if the above disgusts you and you only want to trigger public APIs, you can do this dance:

>>> l = asyncio.Lock()
>>> await l.acquire()  # first acquire will just work
True
>>> try:
...   # second acquire will block so we time it out
...   await asyncio.wait_for(l.acquire(), 0.1)
... except asyncio.TimeoutError:
...   pass
...
>>> l.release()

Now the lock is fully initialized and we can use it:

>>> c = asyncio.Condition(l)

Both workarounds should be compatible with Python 3.7+ asyncio.
History
Date User Action Args
2021-10-08 21:16:42lukasz.langasetrecipients: + lukasz.langa, asvetlov, yselivanov, simonw, uriyyo
2021-10-08 21:16:42lukasz.langasetmessageid: <1633727802.06.0.781167329942.issue45416@roundup.psfhosted.org>
2021-10-08 21:16:42lukasz.langalinkissue45416 messages
2021-10-08 21:16:41lukasz.langacreate