diff options
author | Christian Häggström <kalvdans@gmail.com> | 2020-03-30 13:42:15 +0200 |
---|---|---|
committer | Christian Häggström <kalvdans@gmail.com> | 2020-03-30 13:42:15 +0200 |
commit | b92365a082b659459db78bc8b6fb509eb6737e8d (patch) | |
tree | b6f2fc9376e13aced89f985196e507b7887b1c87 | |
parent | 3a6ae5a630589a29af8d8bd45616d7aadb2fb3db (diff) | |
download | pyserial-git-b92365a082b659459db78bc8b6fb509eb6737e8d.tar.gz |
Don't catch the SerialException we just raised
In Python3 we get double tracebacks for this error:
Traceback (most recent call last):
File "/home/chn/repo/pyserial/serial/serialposix.py", line 557, in read
raise SerialException(
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test/test_exceptions.py", line 26, in <module>
test_unexpected_eof()
File "/usr/lib/python3.8/unittest/mock.py", line 1348, in patched
return func(*newargs, **newkeywargs)
File "test/test_exceptions.py", line 21, in test_unexpected_eof
s.read()
File "/home/chn/repo/pyserial/serial/serialposix.py", line 566, in read
raise SerialException('read failed: {}'.format(e))
serial.serialutil.SerialException: read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
The patch moves the checking for EOF to after the IO block, resulting
in a much nicer traceback. This is the test script (Python3-specific):
from unittest import mock
import serial
import select
import os
@mock.patch('select.select')
@mock.patch('os.read')
def test_unexpected_eof(mock_read, mock_select):
s = serial.Serial()
s.is_open = True
s.fd = 99
s.pipe_abort_read_r = 98
mock_select.return_value = ([99],[],[])
mock_read.return_value = b''
try:
s.read()
except serial.SerialException as e:
if e.__context__: raise
if __name__ == '__main__':
test_unexpected_eof()
-rw-r--r-- | serial/serialposix.py | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/serial/serialposix.py b/serial/serialposix.py index 334ba9f..d5d6397 100644 --- a/serial/serialposix.py +++ b/serial/serialposix.py @@ -548,16 +548,6 @@ class Serial(SerialBase, PlatformSpecific): if not ready: break # timeout buf = os.read(self.fd, size - len(read)) - # read should always return some data as select reported it was - # ready to read when we get to this point. - if not buf: - # Disconnected devices, at least on Linux, show the - # behavior that they are always ready to read immediately - # but reading returns nothing. - raise SerialException( - 'device reports readiness to read but returned no data ' - '(device disconnected or multiple access on port?)') - read.extend(buf) except OSError as e: # this is for Python 3.x where select.error is a subclass of # OSError ignore BlockingIOErrors and EINTR. other errors are shown @@ -570,6 +560,18 @@ class Serial(SerialBase, PlatformSpecific): # see also http://www.python.org/dev/peps/pep-3151/#select if e[0] not in (errno.EAGAIN, errno.EALREADY, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR): raise SerialException('read failed: {}'.format(e)) + else: + # read should always return some data as select reported it was + # ready to read when we get to this point. + if not buf: + # Disconnected devices, at least on Linux, show the + # behavior that they are always ready to read immediately + # but reading returns nothing. + raise SerialException( + 'device reports readiness to read but returned no data ' + '(device disconnected or multiple access on port?)') + read.extend(buf) + if timeout.expired(): break return bytes(read) |