Hello,I've seen that, when setting a timeout, readuntil calls (or other read calls) on serial objects don't raise an exception if timeout occurs; they simply return, with no way for the caller to understand whether the read succeeded (until the terminator) or not. Or, if there's any, I couldn't tell.This is rather different from common nonblocking file handling behaviour (where an exception is raised if no data is available for such timeout) or at least there's a way to understand if there's data somewhere (e.g.
The select call).Was this a design choice? Would you be interested in a contributed patch with some backward-compatible option that raises a TimeoutException or something like that when a timeout happens? I think we have very different views on what is 'sane':-)I think a sane function all either a) does what it's expected to do, b) raises an exception, c) provides another way for the caller to understand what has happened.
Returning from a function without a way for the caller to know whether it has succeeded. It's a bad design.If I always need to check the terminator is there. What's the purpose of readuntil?
I can just read one byte each time and append it to a buffer, until I get the terminator, I get the same complexity.Also, as you will know, when UNIX socket programming, if I get a timeout, an error is set, EAGAIN or EWOULDBLOCK. This is quite a standard way, so the difference in your library is surprising, probably to most programmers having worked with other implementations.More than that: I would expect that readuntil could actually return without the terminator, in one crucial case: when the other side closed the connection. In THAT situation, I could need to accept the fact and handle it by myself (but if it were me, I'd probably raise an exception, maybe a specific one). But your library leaves me with no choice, since I can't understand whether it's the timeout that has expired, or the other side has closed the connection.An alternative which doesn't raise an exception would be to provide a 'success' flag, e.g. Return a tuple from your function, something like (status, bytes); the first value could be something like 'success' (e.g.
Read until terminator), 'timeoutexpired', 'fileclosed', the other the actual bytes.For your other concern: You should do this anyways because if could also happen that the function read some bytes but not up to a terminator. In this case it would be wrong to raise an exception as these bytes would be lostThis looks an implementation issue to me, not an interface design matter. If I understood it properly.
Readuntil should buffer read bytes and make them available to further read or readuntil calls; nothing mandates that once you exit the function, such bytes should be lost. I don't understand whether you're mocking me or you're serious.Are you claiming that, if I set a timeout on a socket, recv will just return what has read and go on? Yes sockets rise a timeout exception when they time-out but if you do not reach the timeout, recv returns the bytes that are available and does not block until the number of bytes requested is received, that's what i was referring to (back then, more than a decade ago (14yrs), when the pySerial API was designed, Python 1.5.2 and 2.2 did not have a timeout on sockets). Anyway, there is no point in discussing, socket.recv as I only tried to explain a design decision for pySerial that was made a long time ago.You can not easily compare sockets with serial ports. While sockets have a concept of closing a connection and the other end can be there or getting lost, there is no such clear concept for the serial port.
While some appliances use the control lines to signal their presence, it's certainly not common to all devices. That's why serial read returns just one byte and not 'all' like read on files does. There is no concept of an 'end' that applies to all serial devices.Comparing pipes (or files), that have no timeout, with serial ports that have one (even more than one;-) also can not deliver a definitive answer.If read would support raising an exception after a timeout, then a few problems arise. When there is already data received: does it throw away that data (bad) or attach the data to the TimeoutException (awkward) or does it successfully return the data on the first call, remember the error and raise the exception on the next call (probably surprising.)?My concerns are that any of these alternatives would surprise the user more than the current solution and some solutions would add quite some complexity to the implementation of pySerial.
Serial Timeout Exception Python Download
The 'usual' approach is to buffer everything locally and then provide the client with what it requires; this is typical of async implementations, i.e. Twisted in Python.There's data, any data? Just read it and cache it locally always, as a first step: self.buffer += datathen, go on processing readuntil, if the terminator is in the current buffer you just pick the data in the buffer up to that, you remove it from the buffer, and you return it to the caller.
If a timeout expires, the data is still in the buffer and can be read by successive client calls; nothing gets lost.Anyway, I wasn't advocating changing how pyserial works now, as it would break current clients. Maybe a new class or utility function that 'wraps' serial objects would be fine.But, forget it. Probably your idea of pyserial is of a much lower level tool than I'd expect; I was sincerely puzzled by readuntil, because it looked like an 'higher level' method, while it really wasn't.bye! Yeah that readuntil. It's there because it was there and landed there because users wanted it. I guess I have never used it in one of my own programs.I usually work differently, that's why i added the class and threading helper to pySerial itself.
Such a class can then buffer and provide methods for commands with a real timeout. (and there I also prefer exceptions on timeouts;-) This is more flexible and also makes it easy to handle different 'streams' of data on the serial port, like logging or event messages in parallel to responses to commands. Most devices I work with have that property (that they may send data on their own, such as logging). Completely agreed with alanfranz, if the user has specified a timeout in the constructor, then this timeout should raise an exception, just like any other synchronous communication library.
Python Wait For Serial Input
This is basic good practice programming.If the user request a line with readline or readuntil with an specified amount of data to receive, then the user could handle an error if not or not enough data is receive.If the user want to read as much as possible datas, then he should read char by char and set a manual timer in a loop.