Skip to content

Commit 0635fb0

Browse files
authored
Remove loop parameter from client/server (#999)
* Remove loop parameter.
1 parent da78590 commit 0635fb0

File tree

8 files changed

+57
-81
lines changed

8 files changed

+57
-81
lines changed

pymodbus/client/asynchronous/async_io/__init__.py

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -231,19 +231,18 @@ class ReconnectingAsyncioModbusTcpClient:
231231
#: Maximum delay in milli seconds before reconnect is attempted.
232232
DELAY_MAX_MS = 1000 * 60 * 5
233233

234-
def __init__(self, protocol_class=None, loop=None, framer=None, **kwargs):
234+
def __init__(self, protocol_class=None, framer=None, **kwargs):
235235
"""Initialize ReconnectingAsyncioModbusTcpClient.
236236
237237
:param protocol_class: Protocol used to talk to modbus device.
238-
:param loop: Event loop to use
239238
"""
239+
# If there are no loop running a runtime error will be raised
240+
self.loop = asyncio.get_running_loop()
240241
#: Protocol used to talk to modbus device.
241242
self.protocol_class = protocol_class or ModbusClientProtocol
242243
#: Current protocol instance.
243244
self.protocol = None
244245
self.framer = framer if framer else ModbusSocketFramer
245-
#: Event loop to use.
246-
self.loop = loop or asyncio.get_event_loop()
247246
self.host = None
248247
self.port = 0
249248
self.connected = False
@@ -341,21 +340,20 @@ async def _reconnect(self):
341340
class AsyncioModbusTcpClient:
342341
"""Client to connect to modbus device over TCP/IP."""
343342

344-
def __init__(self, host=None, port=502, protocol_class=None, loop=None, framer=None, **kwargs):
343+
def __init__(self, host=None, port=502, protocol_class=None, framer=None, **kwargs):
345344
"""Initialize Asyncio Modbus Tcp Client
346345
347346
:param host: Host IP address
348347
:param port: Port to connect
349348
:param protocol_class: Protocol used to talk to modbus device.
350-
:param loop: Asyncio Event loop
351349
"""
350+
# If there are no loop running a runtime error will be raised
351+
self.loop = asyncio.get_running_loop()
352352
#: Protocol used to talk to modbus device.
353353
self.protocol_class = protocol_class or ModbusClientProtocol
354354
#: Current protocol instance.
355355
self.protocol = None
356356
self.framer = framer if framer else ModbusSocketFramer
357-
#: Event loop to use.
358-
self.loop = loop or asyncio.get_event_loop()
359357

360358
self.host = host
361359
self.port = port
@@ -419,17 +417,18 @@ def protocol_lost_connection(self, protocol):
419417
class ReconnectingAsyncioModbusTlsClient(ReconnectingAsyncioModbusTcpClient):
420418
"""Client to connect to modbus device repeatedly over TLS."""
421419

422-
def __init__(self, protocol_class=None, loop=None, framer=None, **kwargs):
420+
def __init__(self, protocol_class=None, framer=None, **kwargs):
423421
"""Initialize ReconnectingAsyncioModbusTcpClient
424422
425423
:param protocol_class: Protocol used to talk to modbus device.
426-
:param loop: Event loop to use
427424
"""
425+
# If there are no loop running a runtime error will be raised
426+
self.loop = asyncio.get_running_loop()
428427
self.framer = framer if framer else ModbusTlsFramer
429428
self.server_hostname = None
430429
self.sslctx = None
431430
ReconnectingAsyncioModbusTcpClient.__init__(
432-
self, protocol_class, loop, framer=self.framer, **kwargs
431+
self, protocol_class, framer=self.framer, **kwargs
433432
)
434433

435434
async def start(self, host, port=802, sslctx=None, server_hostname=None):
@@ -489,19 +488,18 @@ class ReconnectingAsyncioModbusUdpClient:
489488
#: Maximum delay in milli seconds before reconnect is attempted.
490489
DELAY_MAX_MS = 1000 * 60 * 5
491490

492-
def __init__(self, protocol_class=None, loop=None, framer=None, **kwargs):
491+
def __init__(self, protocol_class=None, framer=None, **kwargs):
493492
"""Initialize ReconnectingAsyncioModbusUdpClient
494493
495494
:param protocol_class: Protocol used to talk to modbus device.
496-
:param loop: Asyncio Event loop
497495
"""
496+
# If there are no loop running a runtime error will be raised
497+
self.loop = asyncio.get_running_loop()
498498
#: Protocol used to talk to modbus device.
499499
self.protocol_class = protocol_class or ModbusUdpClientProtocol
500500
#: Current protocol instance.
501501
self.protocol = None
502502
self.framer = framer if framer else ModbusSocketFramer
503-
#: Event loop to use.
504-
self.loop = loop or asyncio.get_event_loop()
505503

506504
self.host = None
507505
self.port = 0
@@ -607,25 +605,22 @@ async def _reconnect(self):
607605
class AsyncioModbusUdpClient:
608606
"""Client to connect to modbus device over UDP."""
609607

610-
def __init__(self, host=None, port=502, protocol_class=None, loop=None, framer=None, **kwargs):
608+
def __init__(self, host=None, port=502, protocol_class=None, framer=None, **kwargs):
611609
"""Initialize Asyncio Modbus UDP Client.
612610
613611
:param host: Host IP address
614612
:param port: Port to connect
615613
:param protocol_class: Protocol used to talk to modbus device.
616-
:param loop: Asyncio Event loop
617614
"""
615+
# If there are no loop running a runtime error will be raised
616+
self.loop = asyncio.get_running_loop()
618617
#: Protocol used to talk to modbus device.
619618
self.protocol_class = protocol_class or ModbusUdpClientProtocol
620619
#: Current protocol instance.
621620
self.protocol = None
622621
self.framer = framer if framer else ModbusSocketFramer
623-
#: Event loop to use.
624-
self.loop = loop or asyncio.get_event_loop()
625-
626622
self.host = host
627623
self.port = port
628-
629624
self.connected = False
630625
self._proto_args = kwargs
631626

@@ -704,7 +699,6 @@ def __init__(
704699
port,
705700
protocol_class=None,
706701
framer=None,
707-
loop=None,
708702
baudrate=9600,
709703
bytesize=8,
710704
parity="N",
@@ -716,14 +710,13 @@ def __init__(
716710
:param port: Port to connect
717711
:param protocol_class: Protocol used to talk to modbus device.
718712
:param framer: Framer to use
719-
:param loop: Asyncio Event loop
720713
"""
714+
# If there are no loop running a runtime error will be raised
715+
self.loop = asyncio.get_running_loop()
721716
#: Protocol used to talk to modbus device.
722717
self.protocol_class = protocol_class or ModbusRtuFramer
723718
#: Current protocol instance.
724719
self.protocol = None
725-
#: Event loop to use.
726-
self.loop = loop or asyncio.get_event_loop()
727720
self.port = port
728721
self.baudrate = baudrate
729722
self.bytesize = bytesize
@@ -797,26 +790,24 @@ def protocol_lost_connection(self, protocol):
797790
_logger.error(TEST_FACTORY)
798791

799792

800-
async def init_tcp_client(proto_cls, loop, host, port, **kwargs):
793+
async def init_tcp_client(proto_cls, host, port, **kwargs):
801794
"""Initialize tcp client with helper function.
802795
803796
:param proto_cls:
804-
:param loop:
805797
:param host:
806798
:param port:
807799
:param kwargs:
808800
:return:
809801
"""
810802
client = ReconnectingAsyncioModbusTcpClient(
811-
protocol_class=proto_cls, loop=loop, **kwargs
803+
protocol_class=proto_cls, **kwargs
812804
)
813805
await client.start(host, port)
814806
return client
815807

816808

817809
async def init_tls_client(
818810
proto_cls,
819-
loop,
820811
host,
821812
port,
822813
sslctx=None,
@@ -827,7 +818,6 @@ async def init_tls_client(
827818
"""Initialize tcp client with Helper function.
828819
829820
:param proto_cls:
830-
:param loop:
831821
:param host:
832822
:param port:
833823
:param sslctx:
@@ -837,24 +827,23 @@ async def init_tls_client(
837827
:return:
838828
"""
839829
client = ReconnectingAsyncioModbusTlsClient(
840-
protocol_class=proto_cls, loop=loop, framer=framer, **kwargs
830+
protocol_class=proto_cls, framer=framer, **kwargs
841831
)
842832
await client.start(host, port, sslctx, server_hostname)
843833
return client
844834

845835

846-
async def init_udp_client(proto_cls, loop, host, port, **kwargs):
836+
async def init_udp_client(proto_cls, host, port, **kwargs):
847837
"""Initialize UDP client with helper function.
848838
849839
:param proto_cls:
850-
:param loop:
851840
:param host:
852841
:param port:
853842
:param kwargs:
854843
:return:
855844
"""
856845
client = ReconnectingAsyncioModbusUdpClient(
857-
protocol_class=proto_cls, loop=loop, **kwargs
846+
protocol_class=proto_cls, **kwargs
858847
)
859848
await client.start(host, port)
860849
return client

pymodbus/client/asynchronous/factory/serial.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def async_io_factory(port=None, framer=None, **kwargs):
2626

2727
proto_cls = kwargs.get("proto_cls") or ModbusClientProtocol
2828

29-
client = AsyncioModbusSerialClient(port, proto_cls, framer, loop, **kwargs)
29+
client = AsyncioModbusSerialClient(port, proto_cls, framer, **kwargs)
3030
coro = client.connect
3131
if not loop.is_running():
3232
loop.run_until_complete(coro())

pymodbus/client/asynchronous/factory/tcp.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ def async_io_factory(host="127.0.0.1", port=Defaults.Port, **kwargs):
2626

2727
if not loop.is_running():
2828
asyncio.set_event_loop(loop)
29-
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)
29+
cor = init_tcp_client(proto_cls, host, port, **kwargs)
3030
client = loop.run_until_complete(asyncio.gather(cor))[0]
3131

3232
elif loop is asyncio.get_event_loop():
33-
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)
33+
cor = init_tcp_client(proto_cls, host, port, **kwargs)
3434
client = asyncio.create_task(cor)
3535
else:
36-
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)
36+
cor = init_tcp_client(proto_cls, host, port, **kwargs)
3737
future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
3838
client = future.result()
3939

pymodbus/client/asynchronous/factory/tls.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ def async_io_factory(
3636
if not loop.is_running():
3737
asyncio.set_event_loop(loop)
3838
cor = init_tls_client(
39-
proto_cls, loop, host, port, sslctx, server_hostname, framer, **kwargs
39+
proto_cls, host, port, sslctx, server_hostname, framer, **kwargs
4040
)
4141
client = loop.run_until_complete(asyncio.gather(cor))[0]
4242
elif loop is asyncio.get_event_loop():
4343
return loop, init_tls_client(
44-
proto_cls, loop, host, port, sslctx, server_hostname, framer, **kwargs
44+
proto_cls, host, port, sslctx, server_hostname, framer, **kwargs
4545
)
4646
else:
4747
cor = init_tls_client(
48-
proto_cls, loop, host, port, sslctx, server_hostname, framer, **kwargs
48+
proto_cls, host, port, sslctx, server_hostname, framer, **kwargs
4949
)
5050
future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
5151
client = future.result()

pymodbus/client/asynchronous/factory/udp.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ def async_io_factory(host="127.0.0.1", port=Defaults.Port, **kwargs):
2323
loop = asyncio.new_event_loop()
2424

2525
proto_cls = kwargs.pop("proto_cls", None)
26-
cor = init_udp_client(proto_cls, loop, host, port, **kwargs)
26+
cor = init_udp_client(proto_cls, host, port, **kwargs)
2727
if not loop.is_running():
28-
cor = init_udp_client(proto_cls, loop, host, port)
28+
cor = init_udp_client(proto_cls, host, port)
2929
client = loop.run_until_complete(asyncio.gather(cor))[0]
3030
elif loop is asyncio.get_event_loop():
31-
return loop, init_udp_client(proto_cls, loop, host, port)
31+
return loop, init_udp_client(proto_cls, host, port)
3232

33-
cor = init_udp_client(proto_cls, loop, host, port)
33+
cor = init_udp_client(proto_cls, host, port)
3434
client = asyncio.run_coroutine_threadsafe(cor, loop=loop)
3535
client = client.result()
3636

pymodbus/server/async_io.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class ModbusDisconnectedRequestHandler(
350350

351351
def __init__(self, owner):
352352
super().__init__(owner)
353-
_future = asyncio.get_event_loop().create_future()
353+
_future = asyncio.get_running_loop().create_future()
354354
self.server.on_connection_terminated = _future
355355

356356
def connection_lost(self, call_exc):
@@ -442,7 +442,7 @@ class ModbusTcpServer: # pylint: disable=too-many-instance-attributes
442442
server context instance.
443443
"""
444444

445-
def __init__( # pylint: disable=too-many-arguments
445+
def __init__(
446446
self,
447447
context,
448448
framer=None,
@@ -453,7 +453,6 @@ def __init__( # pylint: disable=too-many-arguments
453453
allow_reuse_port=False,
454454
defer_start=False,
455455
backlog=20,
456-
loop=None,
457456
**kwargs,
458457
):
459458
"""Initialize the socket server.
@@ -475,8 +474,6 @@ def __init__( # pylint: disable=too-many-arguments
475474
:param backlog: is the maximum number of queued connections
476475
passed to listen(). Defaults to 20, increase if many
477476
connections are being made and broken to your Modbus slave
478-
:param loop: optional asyncio event loop to run in. Will default to
479-
asyncio.get_event_loop() supplied value if None.
480477
:param ignore_missing_slaves: True to not send errors on a request
481478
to a missing slave
482479
:param broadcast_enable: True to treat unit_id 0 as broadcast address,
@@ -485,7 +482,7 @@ def __init__( # pylint: disable=too-many-arguments
485482
response
486483
"""
487484
self.active_connections = {}
488-
self.loop = loop or asyncio.get_event_loop()
485+
self.loop = asyncio.get_running_loop()
489486
self.allow_reuse_address = allow_reuse_address
490487
self.decoder = ServerDecoder()
491488
self.framer = framer or ModbusSocketFramer
@@ -566,7 +563,6 @@ def __init__( # pylint: disable=too-many-arguments
566563
allow_reuse_port=False,
567564
defer_start=False,
568565
backlog=20,
569-
loop=None,
570566
**kwargs,
571567
):
572568
"""Overloaded initializer for the socket server.
@@ -594,8 +590,6 @@ def __init__( # pylint: disable=too-many-arguments
594590
:param backlog: is the maximum number of queued connections
595591
passed to listen(). Defaults to 20, increase if many
596592
connections are being made and broken to your Modbus slave
597-
:param loop: optional asyncio event loop to run in. Will default to
598-
asyncio.get_event_loop() supplied value if None.
599593
:param ignore_missing_slaves: True to not send errors on a request
600594
to a missing slave
601595
:param broadcast_enable: True to treat unit_id 0 as broadcast address,
@@ -613,7 +607,6 @@ def __init__( # pylint: disable=too-many-arguments
613607
allow_reuse_port=allow_reuse_port,
614608
defer_start=defer_start,
615609
backlog=backlog,
616-
loop=loop,
617610
**kwargs,
618611
)
619612
self.sslctx = sslctx_provider(sslctx, certfile, keyfile, password, reqclicert)
@@ -628,7 +621,7 @@ class ModbusUdpServer: # pylint: disable=too-many-instance-attributes
628621
server context instance.
629622
"""
630623

631-
def __init__( # pylint: disable=too-many-arguments
624+
def __init__(
632625
self,
633626
context,
634627
framer=None,
@@ -639,7 +632,6 @@ def __init__( # pylint: disable=too-many-arguments
639632
allow_reuse_port=False,
640633
defer_start=False, # pylint: disable=unused-argument
641634
backlog=20, # pylint: disable=unused-argument
642-
loop=None,
643635
**kwargs,
644636
):
645637
"""Overloaded initializer for the socket server.
@@ -660,7 +652,7 @@ def __init__( # pylint: disable=too-many-arguments
660652
:param response_manipulator: Callback method for
661653
manipulating the response
662654
"""
663-
self.loop = loop or asyncio.get_event_loop()
655+
self.loop = asyncio.get_running_loop()
664656
self.decoder = ServerDecoder()
665657
self.framer = framer or ModbusSocketFramer
666658
self.context = context or ModbusServerContext()

test/test_client_async2.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ def test_udp_asyncio_client(
8484
ModbusAsciiFramer,
8585
],
8686
)
87-
def test_serial_asyncio_client(
87+
@pytest.mark.asyncio
88+
async def test_serial_asyncio_client(
8889
self,
8990
mock_gather, # pylint: disable=unused-argument
9091
mock_event_loop,
@@ -104,6 +105,7 @@ def test_serial_asyncio_client(
104105
parity="E",
105106
stopbits=2,
106107
bytesize=7,
108+
timeout=1,
107109
)
108110
assert isinstance(client, AsyncioModbusSerialClient) # nosec
109111
assert isinstance(client.framer, framer) # nosec
@@ -112,6 +114,7 @@ def test_serial_asyncio_client(
112114
assert client.parity == "E" # nosec
113115
assert client.stopbits == 2 # nosec
114116
assert client.bytesize == 7 # nosec
117+
asyncio.wait_for(client.connect(), timeout=1)
115118
client.stop()
116119
loop.stop()
117120

0 commit comments

Comments
 (0)