From 5386382e58fa957689e6f71ae44a93bc758cb14f Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 10:55:31 +0200 Subject: [PATCH 1/7] Stabilize windows tests. --- pymodbus/client/base.py | 4 ++-- pymodbus/transport/transport.py | 10 ++++++++-- test/test_server_task.py | 12 +++++------- test/transport/test_comm.py | 5 ++++- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py index fc463097c..39c3ca101 100644 --- a/pymodbus/client/base.py +++ b/pymodbus/client/base.py @@ -88,8 +88,8 @@ def __init__( # pylint: disable=too-many-arguments close_comm_on_error: bool = Defaults.CloseCommOnError, strict: bool = Defaults.Strict, broadcast_enable: bool = Defaults.BroadcastEnable, - reconnect_delay: int = Defaults.ReconnectDelay, - reconnect_delay_max: int = Defaults.ReconnectDelayMax, + reconnect_delay: int = 0.1, + reconnect_delay_max: int = 300, on_reconnect_callback: Callable[[], None] | None = None, **kwargs: Any, ) -> None: diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index 80d5263e3..ef3980437 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -13,6 +13,12 @@ from pymodbus.transport.serial_asyncio import create_serial_connection +# Needed due to python 3.8 where Server is not defined +try: + from asyncio import Server as asyncio_server +except ImportError: + asyncio_server: Any = None # type: ignore[no-redef] + with suppress(ImportError): pass @@ -93,7 +99,7 @@ def __init__( ) self.reconnect_delay_current: float = 0 - self.transport: asyncio.BaseTransport | asyncio.Server = None # type: ignore[name-defined] + self.transport: asyncio.BaseTransport | asyncio_server = None self.protocol: asyncio.BaseProtocol = None with suppress(RuntimeError): self.loop: asyncio.AbstractEventLoop = asyncio.get_running_loop() @@ -366,7 +372,7 @@ def close(self, reconnect: bool = False) -> None: Log.debug( "Waiting {} {} ms reconnecting.", self.comm_params.comm_name, - self.reconnect_delay_current, + self.reconnect_delay_current * 1000, ) self.reconnect_timer = self.loop.call_later( self.reconnect_delay_current, diff --git a/test/test_server_task.py b/test/test_server_task.py index 0281dbf0b..df382c65d 100755 --- a/test/test_server_task.py +++ b/test/test_server_task.py @@ -144,7 +144,7 @@ def helper_config(request, def_type): @pytest.mark.parametrize("comm", TEST_TYPES) async def test_async_task_no_server(comm): """Test normal client/server handling.""" - run_server, server_args, run_client, client_args = helper_config(comm, "async") + _run_server, _server_args, run_client, client_args = helper_config(comm, "async") client = run_client(**client_args) try: await client.connect() @@ -215,11 +215,11 @@ async def test_async_task_reuse(comm): @pytest.mark.xdist_group(name="server_serialize") @pytest.mark.parametrize("comm", TEST_TYPES) -async def xtest_async_task_server_stop(comm): +async def test_async_task_server_stop(comm): """Test normal client/server handling.""" run_server, server_args, run_client, client_args = helper_config(comm, "async") task = asyncio.create_task(run_server(**server_args)) - await asyncio.sleep(0.1) + await asyncio.sleep(0.5) on_reconnect_callback = mock.Mock() @@ -243,12 +243,10 @@ async def xtest_async_task_server_stop(comm): await asyncio.sleep(1) timer_allowed = 100 - while not client.transport: + while not client.transport and timer_allowed: await asyncio.sleep(0.1) timer_allowed -= 1 - if not timer_allowed: - pytest.fail("client do not reconnect") - assert client.transport + assert client.transport, "client do not reconnect" # TBD on_reconnect_callback.assert_called() rr = await client.read_coils(1, 1, slave=0x01) diff --git a/test/transport/test_comm.py b/test/transport/test_comm.py index 4ec158893..5d2ddf07b 100644 --- a/test/transport/test_comm.py +++ b/test/transport/test_comm.py @@ -363,7 +363,10 @@ async def test_connect_reconnect(self): client.setup_tcp(False, "localhost", 5101) assert await client.transport_connect() != (None, None) server.close() - await asyncio.sleep(1) + count = 100 + while client.transport and count: + await asyncio.sleep(0.1) + count -= 1 assert not client.transport assert client.reconnect_timer assert client.reconnect_delay_current == 2 * client.comm_params.reconnect_delay From 6801707f24561df22a29d1727cf4e8e320542270 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 11:04:11 +0200 Subject: [PATCH 2/7] mypy --- pymodbus/transport/transport.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index ef3980437..1c4889718 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -2,8 +2,11 @@ from __future__ import annotations import asyncio -import platform import ssl +import sys + +# Needed due to python 3.8 where Server is not defined +from asyncio import Server as asyncio_server from contextlib import suppress from dataclasses import dataclass from typing import Any, Callable, Coroutine @@ -13,16 +16,6 @@ from pymodbus.transport.serial_asyncio import create_serial_connection -# Needed due to python 3.8 where Server is not defined -try: - from asyncio import Server as asyncio_server -except ImportError: - asyncio_server: Any = None # type: ignore[no-redef] - -with suppress(ImportError): - pass - - class BaseTransport: """Base class for transport types. @@ -113,7 +106,7 @@ def __init__( # ----------------------------- # def setup_unix(self, setup_server: bool, host: str): """Prepare transport unix""" - if platform.system().lower() == "windows": + if sys.platform.startswith("win"): raise RuntimeError("Modbus_unix is not supported on Windows!") self.comm_params.check_done() self.comm_params.done = True From 0f6aa0106466d76bb7e319e175cbe78127ef57fd Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 11:18:22 +0200 Subject: [PATCH 3/7] mypy newtype. --- pymodbus/transport/transport.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index 1c4889718..82dce7e95 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -4,18 +4,22 @@ import asyncio import ssl import sys - -# Needed due to python 3.8 where Server is not defined -from asyncio import Server as asyncio_server from contextlib import suppress from dataclasses import dataclass -from typing import Any, Callable, Coroutine +from typing import Any, Callable, Coroutine, NewType from pymodbus.framer import ModbusFramer from pymodbus.logging import Log from pymodbus.transport.serial_asyncio import create_serial_connection +# Needed due to python 3.8 where Server is not defined +try: + from asyncio import Server as asyncio_server +except ImportError: + NewType("asyncio_server", Any) + + class BaseTransport: """Base class for transport types. From 6c9fcbfbdc3876fd88de0b269e584514facea38c Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 11:51:14 +0200 Subject: [PATCH 4/7] mypy 3. --- pymodbus/transport/transport.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index 82dce7e95..7d3afd2d3 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -6,20 +6,13 @@ import sys from contextlib import suppress from dataclasses import dataclass -from typing import Any, Callable, Coroutine, NewType +from typing import Any, Callable, Coroutine from pymodbus.framer import ModbusFramer from pymodbus.logging import Log from pymodbus.transport.serial_asyncio import create_serial_connection -# Needed due to python 3.8 where Server is not defined -try: - from asyncio import Server as asyncio_server -except ImportError: - NewType("asyncio_server", Any) - - class BaseTransport: """Base class for transport types. @@ -96,7 +89,7 @@ def __init__( ) self.reconnect_delay_current: float = 0 - self.transport: asyncio.BaseTransport | asyncio_server = None + self.transport: asyncio.BaseTransport | asyncio.Server = None # type: ignore[attr-defined, unused-ignore] self.protocol: asyncio.BaseProtocol = None with suppress(RuntimeError): self.loop: asyncio.AbstractEventLoop = asyncio.get_running_loop() From 81f12f462885abfafdb49eafa4a8469a374da87f Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 12:15:24 +0200 Subject: [PATCH 5/7] mypy problem. --- pymodbus/transport/transport.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index 7d3afd2d3..3bcd24e52 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -1,4 +1,6 @@ """Base for all transport types.""" +# mypy: disable-error-code="attr-defined" +# needed because asyncio.Server is not defined (to mypy) in v3.8.16 from __future__ import annotations import asyncio @@ -89,7 +91,7 @@ def __init__( ) self.reconnect_delay_current: float = 0 - self.transport: asyncio.BaseTransport | asyncio.Server = None # type: ignore[attr-defined, unused-ignore] + self.transport: asyncio.BaseTransport | asyncio.Server = None self.protocol: asyncio.BaseProtocol = None with suppress(RuntimeError): self.loop: asyncio.AbstractEventLoop = asyncio.get_running_loop() From 30625f48815a33ee9031993bd9141ce0ea6d3c52 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 12:18:56 +0200 Subject: [PATCH 6/7] mypy again. --- pymodbus/transport/transport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index 3bcd24e52..b03222b9a 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -1,5 +1,5 @@ """Base for all transport types.""" -# mypy: disable-error-code="attr-defined" +# mypy: disable-error-code="name-defined" # needed because asyncio.Server is not defined (to mypy) in v3.8.16 from __future__ import annotations From 8f8497a5a4049e29c9137bc524e7ee8d68b99e30 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 2 Jun 2023 13:12:03 +0200 Subject: [PATCH 7/7] python 3.9 windows. --- test/transport/test_comm.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/test/transport/test_comm.py b/test/transport/test_comm.py index 5d2ddf07b..e810fa332 100644 --- a/test/transport/test_comm.py +++ b/test/transport/test_comm.py @@ -1,6 +1,7 @@ """Test transport.""" import asyncio import os +import sys import time from tempfile import gettempdir @@ -367,12 +368,15 @@ async def test_connect_reconnect(self): while client.transport and count: await asyncio.sleep(0.1) count -= 1 - assert not client.transport - assert client.reconnect_timer - assert client.reconnect_delay_current == 2 * client.comm_params.reconnect_delay - await asyncio.sleep(client.reconnect_delay_current * 1.2) - assert client.transport - assert client.reconnect_timer - assert client.reconnect_delay_current == client.comm_params.reconnect_delay + if not sys.platform.startswith("win"): + assert not client.transport + assert client.reconnect_timer + assert ( + client.reconnect_delay_current == 2 * client.comm_params.reconnect_delay + ) + await asyncio.sleep(client.reconnect_delay_current * 1.2) + assert client.transport + assert client.reconnect_timer + assert client.reconnect_delay_current == client.comm_params.reconnect_delay client.close() server.close()