epson_projector icon indicating copy to clipboard operation
epson_projector copied to clipboard

Use async contextmanager for timeouts

Open mvdwetering opened this issue 11 months ago • 0 comments
trafficstars

When trying to run test_serial.py I got following error.

/home/michel/epson_projector/./test_serial.py:40: DeprecationWarning: There is no current event loop
  loop = asyncio.get_event_loop()
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:epson_projector.projector:Getting POWER info
DEBUG:epson_projector.projector:Getting property PWR
DEBUG:epson_projector.projector_serial:Establishing serial connection
Traceback (most recent call last):
  File "/home/michel/epson_projector/./test_serial.py", line 41, in <module>
    loop.run_until_complete(main_serial())
  File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/michel/epson_projector/./test_serial.py", line 18, in main_serial
    await run()
  File "/home/michel/epson_projector/./test_serial.py", line 25, in run
    data = await projector.get_power()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/michel/epson_projector/epson_projector/projector.py", line 69, in get_power
    power = await self.get_property(command=POWER)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/michel/epson_projector/epson_projector/projector.py", line 80, in get_property
    return await self._projector.get_property(command=command, timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/michel/epson_projector/epson_projector/projector_serial.py", line 90, in get_property
    response = await self.send_request(timeout=timeout, command=command + GET_CR)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/michel/epson_projector/epson_projector/projector_serial.py", line 111, in send_request
    await self.async_init()
  File "/home/michel/epson_projector/epson_projector/projector_serial.py", line 46, in async_init
    with async_timeout.timeout(DEFAULT_TIMEOUT):
TypeError: 'Timeout' object does not support the context manager protocol

This is because async_timeout dropped support for the sync context manager in version 5.0.0 (which was deprecated in 4.0.0). Because requirements.txt says async_timeout>=3.0.0 I ended up with version 5.0.1 installed.

To solve this I changed the calls to use the async contextmanager. The async context manager is also supported on version 3.0.0 of async_timeout so works without needing to change any dependecy versions. I tested with test_serial.py and that works fine. I did not test the others.

On a sidenote, the async_timeout package as a whole has been deprecated in favor of using asyncio.timeout built into Python 3.11 or higher. If you don't mind bumping the minimum required Python version to 3.11 I can also update this PR to remove the need for async_timeout all together.

mvdwetering avatar Nov 29 '24 15:11 mvdwetering