Łukasz Langa <luk...@langa.pl> added the comment:

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.

----------
nosy: +lukasz.langa, uriyyo

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue45416>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to