pymodbus-dev / pymodbus

A full modbus protocol written in python
Other
2.22k stars 907 forks source link

`close()` Coroutine not awaited when using TCP #1892

Closed wlockwood closed 9 months ago

wlockwood commented 9 months ago

Versions

Pymodbus Specific

Async client

Description

(May be a regression bug related to #1365) The context managed implementation for AsyncModbusTcpClient doesn't await close().

I tested this with the example code from the ReadTheDocs and a context-managed clone of the same.

Code and Logs

Context managed

import asyncio
from pymodbus.client import AsyncModbusTcpClient

async def main():
    test_host: str = "my_test_ip"

    client = AsyncModbusTcpClient(test_host)  # Create client object
    with AsyncModbusTcpClient(host=test_host) as client:
        await client.connect()  # connect to device, reconnect automatically
        result = await client.read_coils(2, 3, slave=1)  # get information from device
        print(result.bits[0])  # use information

if __name__ == "__main__":
    asyncio.run(main(), debug=True)

Results in:

client\base.py:368: RuntimeWarning: coroutine 'AsyncModbusTcpClient.close' was never awaited
client\base.py", line 368, in __exit__

Manual

Opening and closing the client manually works and doesn't encounter any exceptions:

import asyncio
from pymodbus.client import AsyncModbusTcpClient

async def main():
    test_host: str = "my_test_ip"
    client = AsyncModbusTcpClient(test_host)  # Create client object
    await client.connect()  # connect to device, reconnect automatically
    result = await client.read_coils(2, 3, slave=1)  # get information from device
    print(result.bits[0])  # use information

if __name__ == "__main__":
    asyncio.run(main(), debug=True)
janiversen commented 9 months ago

It could be a regression, but in your manual example you forgot to call close()

wlockwood commented 9 months ago

I thought I'd confirmed this sufficiently, but the close() that was never awaited was the first, orphaned client - I had it in because I copied it from an example, but didn't notice that I was creating a client then immediately overwriting that client variable.

janiversen commented 9 months ago

to be honest you are not the only one, I thought there was a problem in the library, but looking at your code again, I can see it.

Let us hear if you stumble on other problem