Skip to content

Commit 0049eaf

Browse files
authored
Better error message, when pyserial is missing. (#2299)
1 parent cdcfc6f commit 0049eaf

File tree

3 files changed

+15
-19
lines changed

3 files changed

+15
-19
lines changed

pymodbus/client/serial.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
"""Modbus client async serial communication."""
22
from __future__ import annotations
33

4+
import contextlib
5+
import sys
46
import time
57
from collections.abc import Callable
68
from functools import partial
7-
from typing import TYPE_CHECKING
89

910
from pymodbus.client.base import ModbusBaseClient, ModbusBaseSyncClient
1011
from pymodbus.exceptions import ConnectionException
@@ -14,15 +15,9 @@
1415
from pymodbus.utilities import ModbusTransactionState
1516

1617

17-
try:
18+
with contextlib.suppress(ImportError):
1819
import serial
1920

20-
PYSERIAL_MISSING = False
21-
except ImportError:
22-
PYSERIAL_MISSING = True
23-
if TYPE_CHECKING: # always False at runtime
24-
# type checkers do not understand the Raise RuntimeError in __init__()
25-
import serial
2621

2722
class AsyncModbusSerialClient(ModbusBaseClient):
2823
"""**AsyncModbusSerialClient**.
@@ -82,7 +77,7 @@ def __init__( # pylint: disable=too-many-arguments
8277
on_connect_callback: Callable[[bool], None] | None = None,
8378
) -> None:
8479
"""Initialize Asyncio Modbus Serial Client."""
85-
if PYSERIAL_MISSING:
80+
if "serial" not in sys.modules:
8681
raise RuntimeError(
8782
"Serial client requires pyserial "
8883
'Please install with "pip install pyserial" and try again.'
@@ -191,6 +186,11 @@ def __init__( # pylint: disable=too-many-arguments
191186
framer,
192187
retries,
193188
)
189+
if "serial" not in sys.modules:
190+
raise RuntimeError(
191+
"Serial client requires pyserial "
192+
'Please install with "pip install pyserial" and try again.'
193+
)
194194
self.socket: serial.Serial | None = None
195195
self.last_frame_end = None
196196
self._t0 = float(1 + bytesize + stopbits) / baudrate

pymodbus/transport/serialtransport.py

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import asyncio
55
import contextlib
66
import os
7+
import sys
78

89

910
with contextlib.suppress(ImportError):
@@ -18,6 +19,11 @@ class SerialTransport(asyncio.Transport):
1819
def __init__(self, loop, protocol, url, baudrate, bytesize, parity, stopbits, timeout) -> None:
1920
"""Initialize."""
2021
super().__init__()
22+
if "serial" not in sys.modules:
23+
raise RuntimeError(
24+
"Serial client requires pyserial "
25+
'Please install with "pip install pyserial" and try again.'
26+
)
2127
self.async_loop = loop
2228
self.intern_protocol: asyncio.BaseProtocol = protocol
2329
self.sync_serial = serial.serial_for_url(url, exclusive=True,

test/sub_client/test_client.py

-10
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,6 @@ async def test_client_instanciate(
245245
with pytest.raises(ConnectionException):
246246
client.execute(ModbusRequest(0, 0, 0, False))
247247

248-
async def test_serial_not_installed():
249-
"""Try to instantiate clients."""
250-
with mock.patch(
251-
"pymodbus.client.serial.PYSERIAL_MISSING"
252-
) as _pyserial_missing:
253-
_pyserial_missing = True
254-
with pytest.raises(RuntimeError):
255-
lib_client.AsyncModbusSerialClient("/dev/tty")
256-
257-
258248
async def test_client_modbusbaseclient():
259249
"""Test modbus base client class."""
260250
client = ModbusBaseClient(

0 commit comments

Comments
 (0)