Skip to content

Commit d212d17

Browse files
authored
Merge pull request #622 from riptideio/dev
v2.5.1
2 parents 84424bb + c7a582b commit d212d17

File tree

16 files changed

+226
-102
lines changed

16 files changed

+226
-102
lines changed

.github/workflows/ci.yml

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
name: ${{ matrix.task.name }} - ${{ matrix.os.name }} ${{ matrix.python.name }} ${{ matrix.arch.name }}
2121
runs-on: ${{ matrix.os.runs-on }}
2222
container: ${{ matrix.os.container[matrix.python.docker] }}
23+
# present runtime seems to be about 1 minute 30 seconds
24+
timeout-minutes: 10
2325
strategy:
2426
fail-fast: false
2527
matrix:
@@ -30,7 +32,6 @@ jobs:
3032
os:
3133
- name: Linux
3234
runs-on: ubuntu-latest
33-
python_platform: linux
3435
matrix: linux
3536
container:
3637
2.7: docker://python:2.7-buster
@@ -40,55 +41,67 @@ jobs:
4041
3.9: docker://python:3.9-buster
4142
pypy2: docker://pypy:2-jessie
4243
pypy3: docker://pypy:3-stretch
43-
# - name: Windows
44-
# runs-on: windows-latest
45-
# python_platform: win32
46-
# matrix: windows
47-
# - name: macOS
48-
# runs-on: macos-latest
49-
# python_platform: darwin
50-
# matrix: macos
44+
- name: macOS
45+
runs-on: macos-latest
46+
matrix: macos
47+
- name: Windows
48+
runs-on: windows-latest
49+
matrix: windows
50+
openssl:
51+
x86: win32
52+
x64: win64
5153
python:
5254
- name: CPython 2.7
5355
tox: py27
5456
action: 2.7
5557
docker: 2.7
58+
matrix: 2.7
5659
implementation: cpython
5760
- name: PyPy 2.7
5861
tox: pypy27
5962
action: pypy-2.7
6063
docker: pypy2.7
64+
matrix: 2.7
6165
implementation: pypy
66+
openssl_msvc_version: 2019
6267
- name: CPython 3.6
6368
tox: py36
6469
action: 3.6
6570
docker: 3.6
71+
matrix: 3.6
6672
implementation: cpython
6773
- name: CPython 3.7
6874
tox: py37
6975
action: 3.7
7076
docker: 3.7
77+
matrix: 3.7
7178
implementation: cpython
7279
- name: CPython 3.8
7380
tox: py38
7481
action: 3.8
7582
docker: 3.8
83+
matrix: 3.8
7684
implementation: cpython
7785
- name: CPython 3.9
7886
tox: py39
7987
action: 3.9
8088
docker: 3.9
89+
matrix: 3.9
8190
implementation: cpython
8291
- name: PyPy 3.6
8392
tox: pypy36
8493
action: pypy-3.6
8594
docker: pypy3.6
95+
matrix: 3.6
8696
implementation: pypy
97+
openssl_msvc_version: 2019
8798
- name: PyPy 3.7
8899
tox: pypy37
89100
action: pypy-3.7
90101
docker: pypy3.7
102+
matrix: 3.7
91103
implementation: pypy
104+
openssl_msvc_version: 2019
92105
arch:
93106
- name: x86
94107
action: x86
@@ -105,6 +118,12 @@ jobs:
105118
matrix: macos
106119
arch:
107120
matrix: x86
121+
- os:
122+
matrix: windows
123+
python:
124+
implementation: pypy
125+
arch:
126+
matrix: x64
108127
env:
109128
# Should match name above
110129
JOB_NAME: ${{ matrix.task.name }} - ${{ matrix.os.name }} ${{ matrix.python.name }} ${{ matrix.arch.name }}
@@ -129,7 +148,37 @@ jobs:
129148
pip install --upgrade pip setuptools wheel
130149
pip install --upgrade tox
131150
- uses: twisted/[email protected]
151+
- name: Add PyPy Externals
152+
if: ${{ matrix.os.matrix == 'windows' && matrix.python.implementation == 'pypy'}}
153+
env:
154+
PYPY_EXTERNALS_PATH: ${{ github.workspace }}/pypy_externals
155+
shell: bash
156+
run: |
157+
echo $PYPY_EXTERNALS_PATH
158+
mkdir --parents $(dirname $PYPY_EXTERNALS_PATH)
159+
hg clone https://foss.heptapod.net/pypy/externals/ $PYPY_EXTERNALS_PATH
160+
dir $PYPY_EXTERNALS_PATH
161+
cd $PYPY_EXTERNALS_PATH && hg update win32_14x
162+
echo "INCLUDE=$PYPY_EXTERNALS_PATH/include;$INCLUDE" >> $GITHUB_ENV
163+
echo "LIB=$PYPY_EXTERNALS_PATH/lib;$LIB" >> $GITHUB_ENV
164+
# echo "CL=${{ matrix.PYTHON.CL_FLAGS }}" >> $GITHUB_ENV
165+
- name: Add Brew
166+
if: ${{ matrix.os.matrix == 'macos' && matrix.python.implementation == 'pypy'}}
167+
shell: bash
168+
run: |
169+
brew install [email protected] rust
170+
echo "LDFLAGS=-L$(brew --prefix [email protected])/lib" >> $GITHUB_ENV
171+
echo "CFLAGS=-I$(brew --prefix [email protected])/include" >> $GITHUB_ENV
172+
- name: rustup
173+
if: ${{ matrix.os.matrix == 'windows' && matrix.python.implementation == 'pypy'}}
174+
shell: bash
175+
run: |
176+
rustup target add i686-pc-windows-msvc
132177
- name: Test
178+
env:
179+
# When compiling Cryptography for PyPy on Windows there is a cleanup
180+
# failure. This is CI, it doesn't matter.
181+
PIP_NO_CLEAN: 1
133182
run: |
134183
tox -vv -e ${{ matrix.python.tox }}
135184
- name: Coverage Processing
@@ -161,7 +210,6 @@ jobs:
161210
os:
162211
- name: Linux
163212
runs-on: ubuntu-latest
164-
python_platform: linux
165213
matrix: linux
166214
container:
167215
3.8: docker://python:3.8-buster
@@ -195,6 +243,7 @@ jobs:
195243
# Should match JOB_NAME below
196244
name: ${{ matrix.task.name }} - ${{ matrix.os.name }} ${{ matrix.python.name }} ${{ matrix.arch.name }}
197245
runs-on: ${{ matrix.os.runs-on }}
246+
if: always()
198247
needs:
199248
- test
200249
container: ${{ matrix.os.container[matrix.python.docker] }}
@@ -208,7 +257,6 @@ jobs:
208257
os:
209258
- name: Linux
210259
runs-on: ubuntu-latest
211-
python_platform: linux
212260
matrix: linux
213261
container:
214262
3.8: docker://python:3.8-buster

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
version 2.5.1
2+
----------------------------------------------------------
3+
* Bug fix TCP Repl server.
4+
* Support multiple UID's with REPL server.
5+
* Support serial for URL (sync serial client)
6+
* Bug fix/enhancements, close socket connections only on empty or invalid response
7+
18
version 2.5.0
29
----------------------------------------------------------
310
* Support response types `stray` and `empty` in repl server.

pymodbus/client/sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ def connect(self):
649649
if self.socket:
650650
return True
651651
try:
652-
self.socket = serial.Serial(port=self.port,
652+
self.socket = serial.serial_for_url(self.port,
653653
timeout=self.timeout,
654654
bytesize=self.bytesize,
655655
stopbits=self.stopbits,

pymodbus/repl/server/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def server(ctx, host, web_port, broadcast_support, repl, verbose):
5757
case_sensitive=False),
5858
help="Modbus framer to use")
5959
@click.option("--modbus-port", default="5020", help="Modbus port")
60-
@click.option("--modbus-unit-id", default=[1], multiple=True, help="Modbus unit id")
60+
@click.option("--modbus-unit-id", default=[1], type=int,
61+
multiple=True, help="Modbus unit id")
6162
@click.option("--modbus-config", type=click.Path(exists=True),
6263
help="Path to additional modbus server config")
6364
@click.option("-r", "--randomize", default=0, help="Randomize every `r` reads."

pymodbus/server/reactive/main.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,19 @@ async def start_modbus_server(self, app):
135135
:return:
136136
"""
137137
try:
138-
if isinstance(self._modbus_server, ModbusSerialServer):
139-
if hasattr(asyncio, "create_task"):
138+
if hasattr(asyncio, "create_task"):
139+
if isinstance(self._modbus_server, ModbusSerialServer):
140140
app["modbus_serial_server"] = asyncio.create_task(
141141
self._modbus_server.start())
142-
app["modbus_server"] = asyncio.create_task(
143-
self._modbus_server.serve_forever())
144-
else:
142+
app["modbus_server"] = asyncio.create_task(
143+
self._modbus_server.serve_forever())
144+
else:
145+
if isinstance(self._modbus_server, ModbusSerialServer):
145146
app["modbus_serial_server"] = asyncio.ensure_future(
146147
self._modbus_server.start()
147148
)
148-
app["modbus_server"] = asyncio.ensure_future(
149-
self._modbus_server.serve_forever())
149+
app["modbus_server"] = asyncio.ensure_future(
150+
self._modbus_server.serve_forever())
150151

151152
logger.info("Modbus server started")
152153
except Exception as e:

pymodbus/server/sync.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,16 +327,17 @@ def __init__(self, context, framer=None, identity=None,
327327
self.control = ModbusControlBlock()
328328
self.address = address or ("", Defaults.Port)
329329
self.handler = handler or ModbusConnectedRequestHandler
330-
self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves',
330+
self.ignore_missing_slaves = kwargs.pop('ignore_missing_slaves',
331331
Defaults.IgnoreMissingSlaves)
332-
self.broadcast_enable = kwargs.get('broadcast_enable',
332+
self.broadcast_enable = kwargs.pop('broadcast_enable',
333333
Defaults.broadcast_enable)
334334

335335
if isinstance(identity, ModbusDeviceIdentification):
336336
self.control.Identity.update(identity)
337337

338338
socketserver.ThreadingTCPServer.__init__(self, self.address,
339-
self.handler)
339+
self.handler,
340+
**kwargs)
340341

341342
def process_request(self, request, client):
342343
""" Callback for connecting a new client thread
@@ -456,16 +457,16 @@ def __init__(self, context, framer=None, identity=None, address=None,
456457
self.control = ModbusControlBlock()
457458
self.address = address or ("", Defaults.Port)
458459
self.handler = handler or ModbusDisconnectedRequestHandler
459-
self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves',
460+
self.ignore_missing_slaves = kwargs.pop('ignore_missing_slaves',
460461
Defaults.IgnoreMissingSlaves)
461-
self.broadcast_enable = kwargs.get('broadcast_enable',
462+
self.broadcast_enable = kwargs.pop('broadcast_enable',
462463
Defaults.broadcast_enable)
463464

464465
if isinstance(identity, ModbusDeviceIdentification):
465466
self.control.Identity.update(identity)
466467

467468
socketserver.ThreadingUDPServer.__init__(self,
468-
self.address, self.handler)
469+
self.address, self.handler, **kwargs)
469470
# self._BaseServer__shutdown_request = True
470471

471472
def process_request(self, request, client):

pymodbus/transaction.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,19 +217,20 @@ def execute(self, request):
217217
"/Unable to decode response")
218218
response = ModbusIOException(last_exception,
219219
request.function_code)
220+
self.client.close()
220221
if hasattr(self.client, "state"):
221222
_logger.debug("Changing transaction state from "
222223
"'PROCESSING REPLY' to "
223224
"'TRANSACTION_COMPLETE'")
224225
self.client.state = (
225226
ModbusTransactionState.TRANSACTION_COMPLETE)
226-
self.client.close()
227+
227228
return response
228229
except ModbusIOException as ex:
229230
# Handle decode errors in processIncomingPacket method
230231
_logger.exception(ex)
231-
self.client.close()
232232
self.client.state = ModbusTransactionState.TRANSACTION_COMPLETE
233+
self.client.close()
233234
return ex
234235

235236
def _retry_transaction(self, retries, reason,

pymodbus/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __str__(self):
4141
return '[%s, version %s]' % (self.package, self.short())
4242

4343

44-
version = Version('pymodbus', 2, 5, 0)
44+
version = Version('pymodbus', 2, 5, 1, "rc1")
4545

4646
version.__name__ = 'pymodbus' # fix epydoc error
4747

requirements-tests.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ sqlalchemy>=1.1.15
1414
#wsgiref>=0.1.2
1515
verboselogs >= 1.5
1616
tornado==4.5.3
17-
Twisted[serial]>=20.3.0
17+
# using platform_python_implementation rather than
18+
# implementation_name for Python 2 support
19+
Twisted[conch,serial]>=20.3.0; platform_python_implementation != "PyPy" or sys_platform != "win32"
20+
# pywin32 isn't supported on pypy
21+
# https://github.com/mhammond/pywin32/issues/1289
22+
Twisted[conch]>=20.3.0; platform_python_implementation == "PyPy" and sys_platform == "win32"
1823
zope.interface>=4.4.0
1924
asynctest>=0.10.0

setup.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,12 @@
9797
'sphinx_rtd_theme',
9898
'humanfriendly'],
9999
'twisted': [
100-
'twisted[serial] >= 20.3.0',
101-
'pyasn1 >= 0.1.4',
100+
# using platform_python_implementation rather than
101+
# implementation_name for Python 2 support
102+
'Twisted[conch,serial]>=20.3.0; platform_python_implementation != "PyPy" or sys_platform != "win32"',
103+
# pywin32 isn't supported on pypy
104+
# https://github.com/mhammond/pywin32/issues/1289
105+
'Twisted[conch]>=20.3.0; platform_python_implementation == "PyPy" and sys_platform == "win32"',
102106
],
103107
'tornado': [
104108
'tornado == 4.5.3'

0 commit comments

Comments
 (0)