Open Teraskull opened 2 years ago
According to the documentation, the loop
parameter can be removed and should be replaced by asyncio.run
- https://docs.python.org/3/library/asyncio-task.html#running-an-asyncio-program
async def turn_bulbs_on(bulb1, bulb2):
await asyncio.gather(bulb1.turn_on(PilotBuilder(warm_white=255)), bulb2.turn_on(PilotBuilder(warm_white=255)))
def main:
asyncio.run(async turn_bulbs_on(bulb1, bulb2))
Code is not tested.
To be honest - the example code is a bit out of date 😄
This issue isn't fixed by 5164976. Try the following:
async def light_on():
light = wizlight(BULB_IP)
await light.turn_on()
asyncio.run(light_on())
I haven't looked that deeply into fixing it, as I have a very vague understanding how how WiZ light networking works, but the exception is caused by the pywizlight.wizlight.__del__
function attempting to use the event loop (calling self._async_close
), however there is no guarantee that the __del__
function gets called while there's still an event loop. In the above code, light.__del__
gets called after the asyncio.run
call returns, thus the event loop is closed already.
The example code produces a deprecation exception as well, since calling asyncio.get_event_loop()
is deprecated when it isn't called in an event loop. The fix is not as simple as replacing the example code with loop = asyncio.new_event_loop()
since the pywizlight.wizlight.__del__
function still attempts to destroy the event loop after it is already closed (I assume due to the order of which objects are deleted by the interpreter). Also, "Application developers should typically use the high-level asyncio functions, such as asyncio.run(), and should rarely need to reference the loop object or call its methods."
Removing the pywizlight.wizlight.__del__
function appears to avoid all of the issues, however as I said, I'm not sure how the networking with the lights works/if not explicitly closing the transport even matters.
tl;dr: If you're doing a quick script and want to avoid:
Exception ignored in: <function wizlight.__del__ at ...>
...
RuntimeError: Event loop is closed
One can:
import pywizlight
# in main:
del pywizlight.wizlight.__del__
To avoid the noise.
Running the example code on Python 3.9:
Shows a DeprecationWarning:
Remove
loop=loop
for Python 3.10 compatibility.